Fix miniplayer showing, cardview,remmeber last selected option,

This commit is contained in:
h4h13 2019-10-12 02:31:39 +05:30
parent 0e179d6842
commit b9e3483a47
22 changed files with 154 additions and 380 deletions

View file

@ -51,29 +51,4 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
RetroColorUtil.getColor(it.palette, defaultColor))
}
}
/* protected val defaultFooterColor: Int
get() = ATHUtil.resolveColor(getView().context, R.attr.defaultFooterColor)
protected val albumArtistFooterColor: Int
get() = ATHUtil.resolveColor(getView().context, R.attr.cardBackgroundColor)
override fun onLoadFailed(e: Exception, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
onColorReady(defaultFooterColor)
}
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
super.onResourceReady(resource, glideAnimation)
val defaultColor = defaultFooterColor
onColorReady(if (PreferenceUtil.getInstance(getView().context).isDominantColor)
getDominantColor(resource.bitmap, defaultColor)
else
getColor(resource.palette, defaultColor))
}
abstract fun onColorReady(color: Int)*/
}

View file

@ -62,7 +62,7 @@ class ArtistImageFetcher(
override fun loadData(priority: Priority?): InputStream? {
if (!MusicUtil.isArtistNameUnknown(model.artistName) && PreferenceUtil.isAllowedToDownloadMetadata(context)) {
val artists = model.artistName.split(",|&")
val artists = model.artistName.split(",")
val response = deezerApiService.getArtistImage(artists[0]).execute()
if (!response.isSuccessful) {
@ -97,8 +97,8 @@ class ArtistImageFetcher(
class ArtistImageLoader(
val context: Context,
val deezerApiService: DeezerApiService,
val urlLoader: ModelLoader<GlideUrl, InputStream>
private val deezerApiService: DeezerApiService,
private val urlLoader: ModelLoader<GlideUrl, InputStream>
) : StreamModelLoader<ArtistImage> {
override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
@ -110,10 +110,10 @@ class Factory(
val context: Context
) : ModelLoaderFactory<ArtistImage, InputStream> {
private var deezerApiService: DeezerApiService
private var okhttpFactory: OkHttpUrlLoader.Factory
private var okHttpFactory: OkHttpUrlLoader.Factory
init {
okhttpFactory = OkHttpUrlLoader.Factory(OkHttpClient.Builder()
okHttpFactory = OkHttpUrlLoader.Factory(OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
@ -126,11 +126,11 @@ class Factory(
}
override fun build(context: Context?, factories: GenericLoaderFactory?): ModelLoader<ArtistImage, InputStream> {
return ArtistImageLoader(context!!, deezerApiService, okhttpFactory.build(context, factories))
return ArtistImageLoader(context!!, deezerApiService, okHttpFactory.build(context, factories))
}
override fun teardown() {
okhttpFactory.teardown()
okHttpFactory.teardown()
}
companion object {
@ -139,301 +139,3 @@ class Factory(
}
}
/*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,
private val deezerApiService: DeezerApiService,
private val okHttp: OkHttpClient,
private val model: ArtistImage) : DataFetcher<InputStream> {
@Volatile
private var isCancelled: Boolean = false
private var call: Call<DeezerResponse>? = null
private var streamFetcher: OkHttpStreamFetcher? = null
override fun getDataClass(): Class<InputStream> {
return InputStream::class.java
}
override fun getDataSource(): DataSource {
return DataSource.LOCAL
}
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
try {
if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) {
val artists = model.artistName.split(",")
call = deezerApiService.getArtistImage(artists[0])
call?.enqueue(object : Callback<DeezerResponse> {
override fun onFailure(call: Call<DeezerResponse>, t: Throwable) {
callback.onLoadFailed(Exception(t))
}
override fun onResponse(call: Call<DeezerResponse>, response: Response<DeezerResponse>) {
if (isCancelled) {
callback.onDataReady(null)
return
}
try {
val deezerResponse: DeezerResponse? = response.body()
val url = deezerResponse?.data?.get(0)?.let { getHighestQuality(it) }
streamFetcher = OkHttpStreamFetcher(okHttp, GlideUrl(url))
streamFetcher?.loadData(priority, callback)
} catch (e: Exception) {
callback.onLoadFailed(Exception("No artist image url found"))
}
}
})
}
} catch (e: Exception) {
callback.onLoadFailed(e)
}
}
fun getHighestQuality(imageUrl: Data): String {
return when {
imageUrl.pictureXl.isNotEmpty() -> imageUrl.pictureXl
imageUrl.pictureBig.isNotEmpty() -> imageUrl.pictureBig
imageUrl.pictureMedium.isNotEmpty() -> imageUrl.pictureMedium
imageUrl.pictureSmall.isNotEmpty() -> imageUrl.pictureSmall
imageUrl.picture.isNotEmpty() -> imageUrl.picture
else -> ""
}
}
override fun cleanup() {
if (streamFetcher != null) {
streamFetcher!!.cleanup()
}
}
override fun cancel() {
isCancelled = true
call?.cancel()
if (streamFetcher != null) {
streamFetcher!!.cancel()
}
}
companion object {
val TAG: String = ArtistImageFetcher::class.java.simpleName
}
}
class ArtistImageLoader(private val context: Context,
private val deezerApiService: DeezerApiService,
private val okhttp: OkHttpClient) : ModelLoader<ArtistImage, InputStream> {
override fun buildLoadData(model: ArtistImage, width: Int, height: Int, options: Options): ModelLoader.LoadData<InputStream>? {
return ModelLoader.LoadData(ObjectKey(model.artistName), ArtistImageFetcher(context, deezerApiService, okhttp, model))
}
override fun handles(model: ArtistImage): Boolean {
return true
}
class Factory(private val context: Context) : ModelLoaderFactory<ArtistImage, InputStream> {
private val deezerApiService: DeezerApiService =
DeezerApiService.invoke(DeezerApiService.createDefaultOkHttpClient(context)
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.build())
private val okHttp: OkHttpClient = OkHttpClient.Builder()
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.build()
override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<ArtistImage, InputStream> {
return ArtistImageLoader(context, deezerApiService, okHttp)
}
override fun teardown() {}
}
companion object {
// 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
}
}*/