Rolled back to old style image loading and mosaic

main
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
applicationId "code.name.monkey.retromusic"
versionCode 365
versionName '3.4.000-beta01'
versionCode 366
versionName '3.4.000-beta05'
multiDexEnabled true
@ -120,15 +120,15 @@ dependencies {
implementation 'com.squareup.retrofit2:converter-gson: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:input:3.0.0-alpha1'
implementation 'com.afollestad.material-dialogs:color:3.0.0-alpha1'
implementation 'com.afollestad.material-dialogs:bottomsheets:3.0.0-alpha1'
implementation 'com.afollestad.material-dialogs:core:3.1.1'
implementation 'com.afollestad.material-dialogs:input:3.1.1'
implementation 'com.afollestad.material-dialogs:color:3.1.1'
implementation 'com.afollestad.material-dialogs:bottomsheets:3.1.1'
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:okhttp3-integration:4.8.0'
implementation 'com.github.bumptech.glide:glide:3.8.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:1.5.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.9'
@ -158,5 +158,6 @@ dependencies {
kapt 'com.google.dagger:dagger-compiler:2.23.1'
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.activities.base.AbsBaseActivity
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.util.NavigationUtil
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.DeleteSongsDialog
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.glide.GlideApp
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.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder
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.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.activity_album.*
@ -228,11 +229,8 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
}
override fun loadArtistImage(artist: Artist) {
GlideApp.with(this@AlbumDetailsActivity)
.asBitmapPalette()
.load(RetroGlideExtension.getArtistModel(artist))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
ArtistGlideRequest.Builder.from(Glide.with(this), artist)
.generatePalette(this).build()
.dontAnimate()
.into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) {
@ -242,13 +240,11 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
}
private fun loadAlbumCover() {
GlideApp.with(this)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong())
.checkIgnoreMediaStore(this)
.generatePalette(this).build()
.dontAnimate()
.into(object : RetroMusicColoredTarget(image as ImageView) {
.into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(color: Int) {
setColors(color)
}

View File

@ -4,7 +4,6 @@ import android.app.Activity
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
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.song.SimpleSongAdapter
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.glide.GlideApp
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.helper.MusicPlayerRemote
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.model.LastFmArtist
import code.name.monkey.retromusic.util.*
import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.activity_artist_content.*
import kotlinx.android.synthetic.main.activity_artist_details.*
@ -81,7 +80,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
ActivityCompat.postponeEnterTransition(this)
App.musicComponent?.inject(this)
App.musicComponent.inject(this)
artistDetailsPresenter.attachView(this)
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() {
setupRecyclerView()
setupToolbarMarginHeight()
@ -258,23 +262,14 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
private var lang: String? = null
private fun loadArtistImage() {
GlideApp.with(this)
.asBitmapPalette()
.load(RetroGlideExtension.getArtistModel(artist, forceDownload))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
ArtistGlideRequest.Builder.from(Glide.with(this), artist)
.generatePalette(this).build()
.dontAnimate()
.into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) {
setColors(color)
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
setColors(defaultFooterColor)
}
})
forceDownload = false
}
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.activities.base.AbsMusicServiceActivity
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.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import com.bumptech.glide.Glide
import com.r0adkll.slidr.Slidr
import com.r0adkll.slidr.model.SlidrConfig
import com.r0adkll.slidr.model.SlidrListener
@ -98,15 +99,13 @@ class LockScreenActivity : AbsMusicServiceActivity() {
private fun updateSongs() {
val song = MusicPlayerRemote.currentSong
GlideApp.with(this)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
SongGlideRequest.Builder.from(Glide.with(this), song)
.checkIgnoreMediaStore(this)
.generatePalette(this).build()
.dontAnimate()
.into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(color: Int) {
fragment!!.setDark(color)
fragment?.setDark(color)
}
})
}

View File

@ -1,7 +1,6 @@
package code.name.monkey.retromusic.activities
import android.content.*
import android.content.pm.PackageManager
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
@ -83,7 +82,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
if (currentVersion != PreferenceUtil.getInstance(this).lastChangelogVersion) {
startActivityForResult(Intent(this, WhatsNewActivity::class.java), APP_INTRO_REQUEST)
}
} catch (e: PackageManager.NameNotFoundException) {
} catch (e: Throwable) {
e.printStackTrace()
}
@ -112,17 +111,14 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
PreferenceUtil.getInstance(this).unregisterOnSharedPreferenceChangedListener(this)
}
private fun setCurrentFragment(fragment: Fragment, b: Boolean = false) {
val trans = supportFragmentManager.beginTransaction()
trans.replace(R.id.fragment_container, fragment, null)
if (b) {
trans.addToBackStack(null)
private fun setCurrentFragment(fragment: Fragment, tag: String) {
println("setCurrentFragment -> $tag -> ${supportFragmentManager.findFragmentById(R.id.fragment_container)?.tag}")
if (tag != supportFragmentManager.findFragmentById(R.id.fragment_container)?.tag) {
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment, tag).commit()
currentFragment = fragment as MainActivityFragmentCallbacks
}
trans.commit()
currentFragment = fragment as MainActivityFragmentCallbacks
}
private fun restoreCurrentFragment() {
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_playlist,
R.id.action_genre,
R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), false)
R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), false)
R.id.action_folder -> setCurrentFragment(FoldersFragment.newInstance(this), false)
R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), itemId.toString())
R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
R.id.action_folder -> setCurrentFragment(FoldersFragment.newInstance(this), FoldersFragment.TAG)
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.BitmapFactory
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
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.retromusic.R
import code.name.monkey.retromusic.extensions.appHandleColor
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.loaders.AlbumLoader
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.generatePalette
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.request.RequestOptions
import com.bumptech.glide.request.transition.Transition
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
@ -46,23 +46,54 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
override val contentViewLayout: Int
get() = R.layout.activity_album_tag_editor
override fun loadImageFromFile(selectedFile: Uri?) {
GlideApp.with(this).`as`(BitmapPaletteWrapper::class.java)
.load(selectedFile)
.transition(GenericTransitionOptions<BitmapPaletteWrapper>().transition(android.R.anim.fade_in))
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true))
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>() {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)
albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048)
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor)))
override fun loadImageFromFile(selectedFileUri: Uri?) {
Glide.with(this@AlbumTagEditorActivity)
.load(selectedFileUri)
.asBitmap()
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(object : SimpleTarget<BitmapPaletteWrapper>() {
override fun onResourceReady(resource: BitmapPaletteWrapper?, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
RetroColorUtil.getColor(resource?.palette, Color.TRANSPARENT);
albumArtBitmap = resource?.bitmap?.let { ImageUtil.resizeBitmap(it, 2048) }
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource?.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor)))
deleteAlbumArt = false
dataChanged()
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
@ -141,22 +172,26 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
val url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.album.image)
if (!TextUtils.isEmpty(url) && url.trim { it <= ' ' }.isNotEmpty()) {
GlideApp.with(this)
.`as`(BitmapPaletteWrapper::class.java)
.load(url)
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.error(R.drawable.default_album_art))
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>() {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048)
setImageBitmap(albumArtBitmap, getColor(resource.palette,
ContextCompat.getColor(this@AlbumTagEditorActivity, R.color.md_grey_500)))
deleteAlbumArt = false
dataChanged()
setResult(Activity.RESULT_OK)
}
})
Glide.with(this@AlbumTagEditorActivity)
.load(url)
.asBitmap()
.transcode( BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.error(R.drawable.default_album_art)
.into( object: SimpleTarget<BitmapPaletteWrapper>() {
override fun onLoadFailed(e: java.lang.Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
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
dataChanged()
setResult(RESULT_OK)
}
});
return
}
if (lastFmAlbum.album.tags.tag.size > 0) {

View File

@ -7,10 +7,10 @@ import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
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.util.RetroUtil.openUrl
import code.name.monkey.retromusic.views.CircularImageView
import com.bumptech.glide.Glide
class ContributorAdapter(
private var contributors: List<Contributor>
@ -56,7 +56,7 @@ class ContributorAdapter(
internal fun bindData(contributor: Contributor) {
title.text = contributor.name
text.text = contributor.summary
GlideApp.with(image.context)
Glide.with(image.context)
.load(contributor.profileImage)
.error(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.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.ArtistGlideRequest
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.menu.SongMenuHelper
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.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide
import java.util.*
@ -44,35 +45,28 @@ class SearchAdapter(
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
when (getItemViewType(position)) {
ALBUM -> {
val album = dataSet!![position] as Album
holder.title!!.text = album.title
holder.text!!.text = album.artistName
GlideApp.with(activity)
.asDrawable()
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.into(holder.image!!)
val album = dataSet?.get(position) as Album
holder.title?.text = album.title
holder.text?.text = album.artistName
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.checkIgnoreMediaStore(activity).build()
.into(holder.image)
}
ARTIST -> {
val artist = dataSet!![position] as Artist
holder.title!!.text = artist.name
holder.text!!.text = MusicUtil.getArtistInfoString(activity, artist)
GlideApp.with(activity)
.asBitmap()
.load(RetroGlideExtension.getArtistModel(artist))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.into(holder.image!!)
val artist = dataSet?.get(position) as Artist
holder.title?.text = artist.name
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
.build().into(holder.image);
}
SONG -> {
val song = dataSet!![position] as Song
holder.title!!.text = song.title
holder.text!!.text = song.albumName
val song = dataSet?.get(position) as Song
holder.title?.text = song.title
holder.text?.text = song.albumName
}
else -> {
holder.title!!.text = dataSet!![position].toString()
holder.title!!.setTextColor(ThemeStore.accentColor(activity))
holder.title?.text = dataSet?.get(position).toString()
holder.title?.setTextColor(ThemeStore.accentColor(activity))
}
}
}

View File

@ -1,7 +1,6 @@
package code.name.monkey.retromusic.adapter
import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
@ -9,16 +8,13 @@ import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.appthemehelper.ThemeStore
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.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
import code.name.monkey.retromusic.interfaces.CabHolder
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.request.RequestOptions
import com.bumptech.glide.signature.MediaStoreSignature
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import java.io.File
@ -32,7 +28,7 @@ class SongFileAdapter(
private val itemLayoutRes: Int,
private val callbacks: Callbacks?,
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 {
this.setHasStableIds(true)
@ -85,25 +81,24 @@ class SongFileAdapter(
}
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) {
holder.image?.let {
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))
} else {
val error = RetroUtil.getTintedVectorDrawable(activity, R.drawable.ic_file_music_white_24dp, iconColor)
GlideApp.with(activity)
val error = RetroUtil.getTintedVectorDrawable(activity, code.name.monkey.retromusic.R.drawable.ic_file_music_white_24dp, iconColor)
Glide.with(activity)
.load(AudioFileCover(file.path))
.transition(GenericTransitionOptions.with<Drawable>(android.R.anim.fade_in))
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.error(error)
.placeholder(error)
.signature(MediaStoreSignature("", file.lastModified(), 0)))
.into(holder.image!!)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.error(error)
.placeholder(error)
.animate(android.R.anim.fade_in)
.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 code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
@ -26,6 +24,7 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
@ -33,7 +32,7 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
dataSet: ArrayList<Album>,
@param:LayoutRes protected var itemLayoutRes: Int,
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>
protected set
@ -97,18 +96,13 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
}
protected open fun setColors(color: Int, holder: ViewHolder) {
if (holder.paletteColorContainer != null) {
holder.paletteColorContainer!!.setBackgroundColor(color)
if (holder.title != null) {
holder.title!!.setTextColor(MaterialValueHelper.getPrimaryTextColor(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.paletteColorContainer?.let {
it.setBackgroundColor(color)
holder.title?.setTextColor(
MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)))
holder.text?.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)))
}
holder.mask?.backgroundTintList = ColorStateList.valueOf(color)
}
protected open fun loadAlbumCover(album: Album, holder: ViewHolder) {
@ -116,21 +110,20 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
return
}
GlideApp.with(activity)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate()
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.checkIgnoreMediaStore(activity)
.generatePalette(activity).build()
.into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(color: Int) {
setColors(color, holder)
override fun onLoadCleared(placeholder: Drawable?) {
super.onLoadCleared(placeholder)
setColors(defaultFooterColor, holder)
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
setColors(defaultFooterColor, holder)
override fun onColorReady(color: Int) {
if (usePalette)
setColors(color, holder)
else
setColors(defaultFooterColor, holder)
}
})
}
@ -178,7 +171,7 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
init {
setImageTransitionName(activity.getString(R.string.transition_album_art))
setImageTransitionName(activity.getString(code.name.monkey.retromusic.R.string.transition_album_art))
if (menu != null) {
menu!!.visibility = View.GONE
}
@ -189,7 +182,7 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
if (isInQuickSelectMode) {
toggleChecked(adapterPosition)
} 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>>()
pairs.add(pairImageView)
val albumPairs: Array<Pair<View, String>> = pairs.toTypedArray()

View File

@ -1,7 +1,6 @@
package code.name.monkey.retromusic.adapter.album
import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -9,16 +8,15 @@ import android.view.ViewGroup
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.LyricsActivity
import code.name.monkey.retromusic.fragments.AlbumCoverStyle
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.SongGlideRequest
import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import java.util.*
@ -72,14 +70,14 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
private val layout: Int
get() {
return when (PreferenceUtil.getInstance(activity).albumCoverStyle) {
AlbumCoverStyle.NORMAL -> R.layout.fragment_album_cover
AlbumCoverStyle.FLAT -> R.layout.fragment_album_flat_cover
AlbumCoverStyle.CIRCLE -> R.layout.fragment_album_circle_cover
AlbumCoverStyle.CARD -> R.layout.fragment_album_card_cover
AlbumCoverStyle.MATERIAL -> R.layout.fragment_album_material_cover
AlbumCoverStyle.FULL -> R.layout.fragment_album_full_cover
AlbumCoverStyle.FULL_CARD -> R.layout.fragment_album_full_card_cover
else -> R.layout.fragment_album_cover
AlbumCoverStyle.NORMAL -> code.name.monkey.retromusic.R.layout.fragment_album_cover
AlbumCoverStyle.FLAT -> code.name.monkey.retromusic.R.layout.fragment_album_flat_cover
AlbumCoverStyle.CIRCLE -> code.name.monkey.retromusic.R.layout.fragment_album_circle_cover
AlbumCoverStyle.CARD -> code.name.monkey.retromusic.R.layout.fragment_album_card_cover
AlbumCoverStyle.MATERIAL -> code.name.monkey.retromusic.R.layout.fragment_album_material_cover
AlbumCoverStyle.FULL -> code.name.monkey.retromusic.R.layout.fragment_album_full_cover
AlbumCoverStyle.FULL_CARD -> code.name.monkey.retromusic.R.layout.fragment_album_full_card_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? {
val finalLayout = when {
PreferenceUtil.getInstance(activity).nowPlayingScreen == NowPlayingScreen.CLASSIC -> R.layout.fragment_album_full_cover
PreferenceUtil.getInstance(activity).carouselEffect() -> R.layout.fragment_album_carousel_cover
PreferenceUtil.getInstance(activity).nowPlayingScreen == NowPlayingScreen.CLASSIC -> code.name.monkey.retromusic.R.layout.fragment_album_full_cover
PreferenceUtil.getInstance(activity).carouselEffect() -> code.name.monkey.retromusic.R.layout.fragment_album_carousel_cover
else -> layout
}
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)) }
return view
}
@ -114,21 +112,13 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
}
private fun loadAlbumCover() {
GlideApp.with(context!!)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song!!))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.dontAnimate()
SongGlideRequest.Builder.from(Glide.with(requireContext()), song)
.checkIgnoreMediaStore(activity)
.generatePalette(activity).build()
.into(object : RetroMusicColoredTarget(albumCover) {
override fun onColorReady(color: Int) {
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 androidx.core.util.Pair
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.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.views.MetalRecyclerViewPager
import com.bumptech.glide.Glide
class AlbumFullWidthAdapter(private val activity: Activity, private val dataSet: ArrayList<Album>, metrics: DisplayMetrics) :
MetalRecyclerViewPager.MetalAdapter<AlbumFullWidthAdapter.FullMetalViewHolder>(metrics) {
@ -67,12 +67,9 @@ class AlbumFullWidthAdapter(private val activity: Activity, private val dataSet:
if (holder.image == null) {
return
}
GlideApp.with(activity)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate()
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.checkIgnoreMediaStore(activity)
.generatePalette(activity).build()
.into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(color: Int) {

View File

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

View File

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

View File

@ -10,33 +10,32 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.util.Pair
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.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.helper.menu.SongMenuHelper
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.CabHolder
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.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialcab.MaterialCab
import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import java.util.*
/**
* Created by hemanths on 13/08/17.
*/
open class SongAdapter @JvmOverloads constructor(protected val activity: AppCompatActivity, dataSet: ArrayList<Song>,
@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>
protected var usePalette = false
@ -105,18 +104,20 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
if (holder.image == null) {
return
}
GlideApp.with(activity).asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
SongGlideRequest.Builder.from(Glide.with(activity), song)
.checkIgnoreMediaStore(activity)
.generatePalette(activity).build()
.into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(color: Int) {
setColors(color, holder)
override fun onLoadCleared(placeholder: Drawable?) {
super.onLoadCleared(placeholder)
setColors(defaultFooterColor, holder)
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
setColors(defaultFooterColor, holder)
override fun onColorReady(color: Int) {
if (usePalette)
setColors(color, holder)
else
setColors(defaultFooterColor, holder)
}
})
}
@ -172,7 +173,7 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
get() = dataSet[adapterPosition]
init {
setImageTransitionName(activity.getString(R.string.transition_album_art))
setImageTransitionName(activity.getString(code.name.monkey.retromusic.R.string.transition_album_art))
if (menu != null) {
menu!!.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
override val song: Song
@ -191,9 +192,9 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
protected open fun onSongMenuItemClick(item: MenuItem): Boolean {
if (image != null && image!!.visibility == View.VISIBLE) {
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,
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)
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.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
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.SongGlideRequest
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.*
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.transition.Transition
class AppWidgetBig : BaseAppWidget() {
@ -46,18 +46,18 @@ class AppWidgetBig : BaseAppWidget() {
*/
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
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.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))
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))
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))
linkButtons(context, appWidgetView)
@ -69,32 +69,32 @@ class AppWidgetBig : BaseAppWidget() {
*/
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName,
R.layout.app_widget_big)
code.name.monkey.retromusic.R.layout.app_widget_big)
val isPlaying = service.isPlaying
val song = service.currentSong
// Set the titles and artwork
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 {
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song))
appWidgetView.setViewVisibility(code.name.monkey.retromusic.R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(code.name.monkey.retromusic.R.id.title, song.title)
appWidgetView.setTextViewText(code.name.monkey.retromusic.R.id.text, getSongArtistAndAlbum(song))
}
// 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(
RetroUtil.getTintedVectorDrawable(service, playPauseRes,
MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f))
// Set prev/next button drawables
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))
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))
// Link actions buttons to intents
@ -106,19 +106,18 @@ class AppWidgetBig : BaseAppWidget() {
val appContext = service.applicationContext
service.runOnUiThread {
if (target != null) {
GlideApp.with(appContext).clear(target)
Glide.clear(target)
}
target = GlideApp.with(appContext)
.asBitmap()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
.checkIgnoreMediaStore(appContext)
.asBitmap().build()
.into(object : SimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) {
override fun onResourceReady(resource: Bitmap, glideAnimation: GlideAnimation<in Bitmap>) {
update(resource)
}
override fun onLoadFailed(errorDrawable: Drawable?) {
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null)
}
@ -130,7 +129,7 @@ class AppWidgetBig : BaseAppWidget() {
}
pushUpdate(appContext, appWidgetIds, appWidgetView)
}
})
});
}
}
@ -165,9 +164,7 @@ class AppWidgetBig : BaseAppWidget() {
companion object {
const val NAME: String = "app_widget_big"
private var mInstance: AppWidgetBig? = null
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.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
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.SongGlideRequest
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.ImageUtil
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.transition.Transition
class AppWidgetCard : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -79,15 +81,15 @@ class AppWidgetCard : BaseAppWidget() {
// Set correct drawable for pause state
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,
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f))
// 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,
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,
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f))
@ -95,46 +97,42 @@ class AppWidgetCard : BaseAppWidget() {
linkButtons(service, appWidgetView)
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) {
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
// Load the album cover async and push the update on completion
service.runOnUiThread {
if (target != null) {
GlideApp.with(appContext).clear(target)
Glide.clear(target)
}
GlideApp.with(appContext)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette
.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true))))
update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true))))
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
}
private fun update(bitmap: Bitmap?, color: Int) {
// Set correct drawable for pause state
val playPauseRest = if (isPlaying) R.drawable.ic_pause_white_24dp
else
R.drawable.ic_play_arrow_white_32dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRest, color)!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, playPauseRes, color)))
// 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_prev, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_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, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)))
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)
pushUpdate(service, appWidgetIds, appWidgetView)

View File

@ -24,19 +24,20 @@ import android.text.TextUtils
import android.view.View
import android.widget.RemoteViews
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants
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.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
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.util.ImageUtil
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.transition.Transition
class AppWidgetClassic : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -92,40 +93,35 @@ class AppWidgetClassic : BaseAppWidget() {
val appContext = service.applicationContext
service.runOnUiThread {
if (target != null) {
GlideApp.with(appContext).clear(target)
Glide.clear(target)
}
GlideApp.with(appContext)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
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?) {
super.onLoadFailed(errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true))
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
}
private fun update(bitmap: Bitmap?, color: Int) {
// Set correct drawable for pause state
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,
createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRes, color)!!, 1f))
val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_24dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, playPauseRes, color)))
// 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_prev, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_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, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)))
val image = getAlbumArtDrawable(service.resources, bitmap)
val roundedBitmap = BaseAppWidget.createRoundedBitmap(image, imageSize, imageSize,
cardRadius, 0f, cardRadius, 0f)
val roundedBitmap = createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0F, cardRadius, 0F)
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
pushUpdate(appContext, appWidgetIds, appWidgetView)
@ -150,15 +146,15 @@ class AppWidgetClassic : BaseAppWidget() {
views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
// Previous track
pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
// Play and pause
pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Next track
pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
}

View File

@ -27,15 +27,15 @@ 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
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.SongGlideRequest
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.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.transition.Transition
class AppWidgetSmall : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -96,23 +96,21 @@ class AppWidgetSmall : BaseAppWidget() {
val appContext = service.applicationContext
service.runOnUiThread {
if (target != null) {
GlideApp.with(appContext).clear(target);
Glide.clear(target)
}
target = GlideApp.with(appContext)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
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?) {
super.onLoadFailed(errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true))
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
}
private fun update(bitmap: Bitmap?, color: Int) {
@ -121,14 +119,14 @@ class AppWidgetSmall : BaseAppWidget() {
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(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
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_prev, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_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, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)!!, 1f))
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)
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.home.BannerHomeFragment
import dagger.Component
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
*/
@Singleton
@Component(modules = [
RepositoryModule::class,
AlbumModule::class,

View File

@ -18,6 +18,7 @@ import android.app.Activity
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
@ -26,6 +27,7 @@ import dagger.Provides
class ActivityModule(private val activity: Activity) {
@Provides
@Singleton
fun provideActivity(): 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 dagger.Module
import dagger.Provides
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
@ -28,11 +29,13 @@ import dagger.Provides
class AlbumModule {
@Provides
@Singleton
fun providesAlbumsPresenter(presenter: AlbumsPresenterImpl): AlbumsPresenter {
return presenter
}
@Provides
@Singleton
fun providesAlbumDetailsPresenter(presenter: AlbumDetailsPresenterImpl): AlbumDetailsPresenter {
return presenter
}

View File

@ -18,6 +18,7 @@ import android.content.Context
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
@ -26,6 +27,7 @@ import dagger.Provides
class AppModule(private val context: Context) {
@Provides
@Singleton
fun provideContext(): 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.ArtistsPresenter.*
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
@ -29,11 +30,13 @@ import code.name.monkey.retromusic.mvp.presenter.ArtistsPresenter.*
class ArtistModule {
@Provides
@Singleton
fun providesArtistDetailsPresenter(presenter: ArtistDetailsPresenterImpl): ArtistDetailsPresenter {
return presenter
}
@Provides
@Singleton
fun providesArtistsPresenter(presenter: ArtistsPresenterImpl): ArtistsPresenter {
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 dagger.Module
import dagger.Provides
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
@ -28,12 +29,14 @@ import dagger.Provides
class GenreModule {
@Provides
@Singleton
fun providesGenresPresenter(presenter: GenresPresenterImpl): GenresPresenter {
return presenter
}
@Provides
@Singleton
fun providesGenreDetailsPresenter(presenter: GenreDetailsPresenterImpl): GenreDetailsPresenter {
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 dagger.Module
import dagger.Provides
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
@ -26,6 +27,7 @@ import dagger.Provides
class HomeModule {
@Provides
@Singleton
fun providesHomePresenter(presenter: HomePresenterImpl): HomePresenter {
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 dagger.Module
import dagger.Provides
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
@ -27,11 +28,13 @@ import dagger.Provides
@Module
class PlaylistModule {
@Provides
@Singleton
fun providesPlaylistSongPresenter(presenter: PlaylistSongsPresenterImpl): PlaylistSongsPresenter {
return presenter
}
@Provides
@Singleton
fun providesPlaylistsPresenter(presenter: PlaylistsPresenterImpl): PlaylistsPresenter {
return presenter
}

View File

@ -20,6 +20,7 @@ import code.name.monkey.retromusic.providers.RepositoryImpl
import code.name.monkey.retromusic.providers.interfaces.Repository
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
@ -28,6 +29,7 @@ import dagger.Provides
class RepositoryModule {
@Provides
@Singleton
fun providesRepository(context: Context): Repository {
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 dagger.Module
import dagger.Provides
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
@ -26,6 +27,7 @@ import dagger.Provides
class SearchModule {
@Provides
@Singleton
fun providesSearchPresenter(presenter: SearchPresenterImpl): SearchPresenter {
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 dagger.Module
import dagger.Provides
import javax.inject.Singleton
/**
* Created by hemanths on 2019-09-04.
@ -25,6 +26,7 @@ import dagger.Provides
@Module
class SongModule {
@Provides
@Singleton
fun providesSongPresenter(presenter: SongPresenterImpl): SongPresenter {
return presenter
}

View File

@ -13,6 +13,26 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import javax.inject.Inject
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>) {
adapter?.swapDataSet(albums)
}
@ -86,20 +106,6 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
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() {
albumsPresenter.loadAlbums()
}
@ -108,19 +114,14 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
albumsPresenter.loadAlbums()
}
override fun onDestroyView() {
super.onDestroyView()
albumsPresenter.detachView()
}
override fun showEmptyView() {
adapter?.swapDataSet(ArrayList())
}
companion object {
val TAG: String = AlbumsFragment::class.java.simpleName
@JvmField
var TAG: String = AlbumsFragment::class.java.simpleName
fun newInstance(): AlbumsFragment {
val args = Bundle()

View File

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

View File

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

View File

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

View File

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

View File

@ -25,8 +25,7 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
App.musicComponent?.inject(this)
App.musicComponent.inject(this)
songPresenter.attachView(this)
}
@ -117,6 +116,9 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
companion object {
@JvmField
var TAG: String = SongsFragment::class.java.simpleName
fun newInstance(): SongsFragment {
val args = Bundle()
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.show
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.interfaces.MainActivityFragmentCallbacks
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.HomeView
import code.name.monkey.retromusic.util.*
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
@ -101,15 +101,14 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
App.musicComponent?.inject(this)
homePresenter.attachView(this)
App.musicComponent.inject(this)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
toolbar = view.findViewById(R.id.toolbar)
bannerImage?.setOnClickListener {
@ -146,7 +145,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
}
titleWelcome.setTextColor(ThemeStore.textColorPrimary(requireContext()))
titleWelcome.text = String.format("%s", PreferenceUtil.getInstance(requireContext()).userName)
homePresenter.attachView(this)
homePresenter.loadSections()
}
@ -254,7 +253,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
private fun loadTimeImage(day: String) {
if (bannerImage != null) {
if (PreferenceUtil.getInstance(requireContext()).bannerImage.isEmpty()) {
GlideApp.with(requireActivity())
Glide.with(requireActivity())
.load(day)
.placeholder(R.drawable.material_design_default)
.diskCacheStrategy(DiskCacheStrategy.ALL)
@ -277,10 +276,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
const val TAG: String = "BannerHomeFragment"
fun newInstance(): BannerHomeFragment {
val args = Bundle()
val fragment = BannerHomeFragment()
fragment.arguments = args
return fragment
return BannerHomeFragment()
}
}
}

View File

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

View File

@ -1,27 +1,26 @@
package code.name.monkey.retromusic.fragments.player.cardblur
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.preference.PreferenceManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.preference.PreferenceManager
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
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.player.PlayerAlbumCoverFragment
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.*
class CardBlurFragment : AbsPlayerFragment() {
class CardBlurFragment : AbsPlayerFragment() {
override fun playerToolbar(): Toolbar {
return playerToolbar
}
@ -125,17 +124,13 @@ class CardBlurFragment : AbsPlayerFragment() {
private fun updateBlur() {
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()
GlideApp.with(activity)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.transition(RetroGlideExtension.getDefaultTransition())
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
.checkIgnoreMediaStore(requireContext())
.generatePalette(requireContext()).build()
.transform(BlurTransformation.Builder(activity).blurRadius(blurAmount.toFloat()).build())
.songOptions(MusicPlayerRemote.currentSong)
.centerCrop()
.override(320, 480)
.into(object : RetroMusicColoredTarget(colorBackground) {
override fun onColorReady(color: Int) {
@ -143,11 +138,6 @@ class CardBlurFragment : AbsPlayerFragment() {
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.activities.LyricsActivity
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.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.helper.MusicPlayerRemote
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.RetroColorUtil
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.*
class ColorFragment : AbsPlayerFragment() {
@ -133,21 +133,20 @@ class ColorFragment : AbsPlayerFragment() {
private fun updateSong() {
GlideApp.with(activity!!)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.songOptions(MusicPlayerRemote.currentSong)
.transition(RetroGlideExtension.getDefaultTransition())
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
.checkIgnoreMediaStore(requireContext())
.generatePalette(requireContext())
.build()
.into(object : RetroMusicColoredTarget(playerImage) {
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)
val background = resource.palette.getColor()
val accentColor = resource.palette.getContrastColor(background)
val palette = resource.palette
val swatch = RetroColorUtil.getSwatch(palette)
@ -158,8 +157,8 @@ class ColorFragment : AbsPlayerFragment() {
setColors(backgroundColor, textColor)
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
override fun onLoadFailed(e: Exception, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
val backgroundColor = defaultFooterColor
val textColor = if (ColorUtil.isColorLight(defaultFooterColor))
MaterialValueHelper.getPrimaryTextColor(context, true)
@ -265,10 +264,6 @@ class ColorFragment : AbsPlayerFragment() {
}
}
fun Palette.getContrastColor(background: Int): Int {
return 0
}
fun Palette.getColor(): Int {
return when {

View File

@ -13,16 +13,16 @@ import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
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.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.ViewUtil
import code.name.monkey.retromusic.views.DrawableGradient
import kotlinx.android.synthetic.main.fragment_flat_player.*
class FlatPlayerFragment : AbsPlayerFragment() {
class FlatPlayerFragment : AbsPlayerFragment() {
override fun playerToolbar(): Toolbar {
return playerToolbar
}

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

View File

@ -77,7 +77,7 @@ class TinyPlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Ca
ThemeStore.accentColor(requireContext())
}
if (ColorUtil.isColorLight(color)) {
if (ColorUtil.isColorLight(colorFinal)) {
textColorPrimary = MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
textColorPrimaryDisabled = MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
} 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 com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
import java.security.MessageDigest
class BlurTransformation : BitmapTransformation {
private var context: Context? = null
private var blurRadius: Float = 0.toFloat()
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) {
this.context = builder.context
this.blurRadius = builder.blurRadius
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? {
val sampling: Int
if (this.sampling == 0) {
@ -99,60 +138,11 @@ class BlurTransformation : BitmapTransformation {
return StackBlur.blur(out, blurRadius)
}
override fun equals(other: Any?): Boolean {
return other is BlurTransformation
}
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)
}
override fun getId(): String {
return "BlurTransformation(radius=$blurRadius, sampling=$sampling)"
}
companion object {
const val DEFAULT_BLUR_RADIUS = 5f
private const val ID = "code.name.monkey.retromusic.glide.BlurTransformation"
val DEFAULT_BLUR_RADIUS = 5f
}
}

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.RetroColorUtil.getColor
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) {
@ -34,13 +34,13 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
protected val albumArtistFooterColor: Int
get() = ATHUtil.resolveColor(getView().context, R.attr.cardBackgroundColor)
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
override fun onLoadFailed(e: Exception, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
onColorReady(defaultFooterColor)
}
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: Transition<in BitmapPaletteWrapper>?) {
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
super.onResourceReady(resource, glideAnimation)
val defaultColor = defaultFooterColor

View File

@ -15,29 +15,22 @@
package code.name.monkey.retromusic.glide
import android.content.Context
import android.graphics.Bitmap
import code.name.monkey.retromusic.glide.artistimage.ArtistImage
import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
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.Registry
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.module.AppGlideModule
import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.module.GlideModule
import java.io.InputStream
@GlideModule
class RetroMusicGlideModule : AppGlideModule() {
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())
class RetroMusicGlideModule : GlideModule {
override fun applyOptions(context: Context, builder: GlideBuilder) {
}
override fun isManifestParsingEnabled(): Boolean {
return false
override fun registerComponents(context: Context, glide: Glide) {
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
import android.content.Context
import code.name.monkey.retromusic.deezer.Data
import code.name.monkey.retromusic.deezer.DeezerApiService
import code.name.monkey.retromusic.deezer.DeezerResponse
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RetroUtil
import android.graphics.Bitmap
import android.graphics.Canvas
import android.media.MediaMetadataRetriever
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverUtils
import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.PreferenceUtil
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.model.GlideUrl
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.MultiModelLoaderFactory
import com.bumptech.glide.signature.ObjectKey
import okhttp3.OkHttpClient
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import com.bumptech.glide.load.model.stream.StreamModelLoader
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.IOException
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 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
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.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable
import io.reactivex.disposables.CompositeDisposable
import javax.inject.Inject
@ -48,7 +48,7 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
private lateinit var album: Album
override fun loadMore(artistId: Int) {
disposable = repository.getArtistByIdFlowable(artistId)
disposable += repository.getArtistByIdFlowable(artistId)
.map {
view.loadArtistImage(it)
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) {
disposable = repository.getAlbumFlowable(albumId)
disposable += repository.getAlbumFlowable(albumId)
.doOnComplete {
view.complete()
}
@ -79,7 +79,7 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
override fun 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.providers.interfaces.Repository
import code.name.monkey.retromusic.rest.model.LastFmArtist
import io.reactivex.disposables.Disposable
import io.reactivex.disposables.CompositeDisposable
import java.util.*
import javax.inject.Inject
@ -49,16 +49,16 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
override fun loadBiography(name: String,
lang: String?,
cache: String?) {
disposable = repository.artistInfoFloable(name, lang, cache)
disposable += repository.artistInfoFloable(name, lang, cache)
.subscribe {
view.artistInfo(it)
}
}
private var disposable: Disposable? = null
private var disposable = CompositeDisposable()
override fun loadArtist(artistId: Int) {
disposable = repository.getArtistByIdFlowable(artistId)
disposable += repository.getArtistByIdFlowable(artistId)
.doOnComplete {
view.complete()
}
@ -67,6 +67,10 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
}
}
override fun detachView() {
super.detachView()
disposable.dispose()
}
private fun showArtist(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.TOP_ALBUMS
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.Playlist
import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import javax.inject.Inject
@ -44,15 +48,16 @@ interface HomePresenter : Presenter<HomeView> {
private val repository: Repository
) : PresenterImpl<HomeView>(), HomePresenter {
override fun loadSections() {
loadRecentArtists()
/*loadRecentArtists()
loadRecentAlbums()
loadTopArtists()
loadATopAlbums()
loadFavorite()
loadFavorite()*/
loadHomeSection()
}
private var disposable: CompositeDisposable = CompositeDisposable()
private val hashSet: HashSet<Home> = HashSet()
private fun showData(sections: ArrayList<Home>) {
if (sections.isEmpty()) {
@ -62,7 +67,7 @@ interface HomePresenter : Presenter<HomeView> {
}
}
private fun loadRecentArtists() {
/*private fun loadRecentArtists() {
disposable += repository.recentArtistsFlowable
.subscribe {
if (it.isNotEmpty()) hashSet.add(
@ -135,8 +140,67 @@ interface HomePresenter : Presenter<HomeView> {
))
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)
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) {
BlacklistStore.getInstance(context).removePath(File(text))
BlacklistStore.getInstance(context).removePath(File(text.toString()))
refreshBlacklistData()
}
negativeButton(android.R.string.cancel)

View File

@ -51,7 +51,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.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.AutoMusicProvider;
import code.name.monkey.retromusic.glide.BlurTransformation;
import code.name.monkey.retromusic.glide.GlideApp;
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.glide.SongGlideRequest;
import code.name.monkey.retromusic.helper.ShuffleHelper;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.Song;
@ -747,27 +747,25 @@ public class MusicService extends MediaBrowserServiceCompat implements SharedPre
if (PreferenceUtil.getInstance(this).albumArtOnLockscreen()) {
final Point screenSize = RetroUtil.getScreenSize(MusicService.this);
GlideRequest request = GlideApp.with(MusicService.this)
.asBitmap()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song);
final BitmapRequestBuilder<?, Bitmap> request = SongGlideRequest.Builder.from(Glide.with(MusicService.this), song)
.checkIgnoreMediaStore(MusicService.this)
.asBitmap().build();
if (PreferenceUtil.getInstance(this).blurredAlbumArt()) {
request.transform(new BlurTransformation.Builder(MusicService.this).build());
}
runOnUiThread(new Runnable() {
@Override
public void run() {
request.into(new RetroSimpleTarget<Bitmap>(screenSize.x, screenSize.y) {
request.into(new SimpleTarget<Bitmap>(screenSize.x, screenSize.y) {
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
super.onLoadFailed(errorDrawable);
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
metaData.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, copy(resource));
mediaSession.setMetadata(metaData.build());
}
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> glideAnimation) {
metaData.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, copy(resource));
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
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.text.Html
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.activities.MainActivity
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.SongGlideRequest
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.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
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.transition.Transition
class PlayingNotificationImpl24 : PlayingNotification() {
private var target: Target<BitmapPaletteWrapper>? = null
@ -74,22 +74,22 @@ class PlayingNotificationImpl24 : PlayingNotification() {
.getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread {
if (target != null) {
GlideApp.with(service).clear(target);
Glide.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>?) {
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
update(resource.bitmap, when {
PreferenceUtil.getInstance(service).isDominantColor -> RetroColorUtil.getDominantColor(resource.bitmap, 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)
}
@ -144,7 +144,7 @@ class PlayingNotificationImpl24 : PlayingNotification() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setStyle(MediaStyle()
.setMediaSession(service.mediaSession.sessionToken)
.setShowActionsInCompactView( 1, 2, 3))
.setShowActionsInCompactView(1, 2, 3))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O && PreferenceUtil.getInstance(service).coloredNotification()) {
builder.color = color

View File

@ -27,9 +27,7 @@ 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.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.model.Song
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.createBitmap
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.transition.Transition
/**
* @author Hemanth S (h4h13).
@ -99,22 +99,21 @@ class PlayingNotificationOreo : PlayingNotification() {
.getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread {
if (target != null) {
GlideApp.with(service).clear(target);
Glide.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>?) {
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
val mediaNotificationProcessor = MediaNotificationProcessor(service, service) { i, _ -> update(resource.bitmap, i) }
mediaNotificationProcessor.processNotification(resource.bitmap)
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
update(null, Color.WHITE)
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null, Color.TRANSPARENT)
}
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.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import com.bumptech.glide.signature.ObjectKey;
import code.name.monkey.retromusic.App;
import com.bumptech.glide.signature.StringSignature;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class ArtistSignatureUtil {
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);
}
public static ArtistSignatureUtil getInstance() {
public static ArtistSignatureUtil getInstance(@NonNull final Context context) {
if (sInstance == null) {
sInstance = new ArtistSignatureUtil(App.Companion.getContext());
sInstance = new ArtistSignatureUtil(context.getApplicationContext());
}
return sInstance;
}
@SuppressLint("CommitPrefEdits")
public void updateArtistSignature(String artistName) {
mPreferences.edit().putLong(artistName, System.currentTimeMillis()).apply();
mPreferences.edit().putLong(artistName, System.currentTimeMillis()).commit();
}
public long getArtistSignatureRaw(String artistName) {
return mPreferences.getLong(artistName, 0);
}
public ObjectKey getArtistSignature(String artistName) {
return new ObjectKey(String.valueOf(getArtistSignatureRaw(artistName)));
public StringSignature getArtistSignature(String artistName) {
return new StringSignature(String.valueOf(getArtistSignatureRaw(artistName)));
}
}

View File

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

View File

@ -36,6 +36,7 @@ import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import code.name.monkey.appthemehelper.util.TintHelper;
@ -277,4 +278,10 @@ public class ImageUtil {
}
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.Nullable;
import com.bumptech.glide.Glide;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.GlideApp;
/**
* @author Hemanth S (h4h13).
@ -49,7 +50,7 @@ public class NetworkImageView extends CircularImageView {
}
public void setImageUrl(@NonNull Context context, @NonNull String imageUrl) {
GlideApp.with(context)
Glide.with(context)
.load(imageUrl)
.error(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());
}
}
}