Fixed crash on coverless albums.
This commit is contained in:
parent
6139591bd1
commit
78468167ca
|
@ -224,13 +224,13 @@ class MainActivity : AppCompatActivity() {
|
|||
now_playing_details_progress.progress = 0
|
||||
|
||||
Picasso.get()
|
||||
.load(normalizeUrl(track.album.cover.original))
|
||||
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
|
||||
.fit()
|
||||
.centerCrop()
|
||||
.into(now_playing_cover)
|
||||
|
||||
Picasso.get()
|
||||
.load(normalizeUrl(track.album.cover.original))
|
||||
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
|
||||
.fit()
|
||||
.centerCrop()
|
||||
.into(now_playing_details_cover)
|
||||
|
|
|
@ -8,7 +8,8 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.github.apognu.otter.R
|
||||
import com.github.apognu.otter.fragments.FunkwhaleAdapter
|
||||
import com.github.apognu.otter.utils.Album
|
||||
import com.github.apognu.otter.utils.normalizeUrl
|
||||
import com.github.apognu.otter.utils.maybeLoad
|
||||
import com.github.apognu.otter.utils.maybeNormalizeUrl
|
||||
import com.squareup.picasso.Picasso
|
||||
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
|
||||
import kotlinx.android.synthetic.main.row_album.view.*
|
||||
|
@ -33,9 +34,8 @@ class AlbumsAdapter(val context: Context?, val listener: OnAlbumClickListener) :
|
|||
val album = data[position]
|
||||
|
||||
Picasso.get()
|
||||
.load(normalizeUrl(album.cover.original))
|
||||
.maybeLoad(maybeNormalizeUrl(album.cover.original))
|
||||
.fit()
|
||||
.placeholder(R.drawable.cover)
|
||||
.transform(RoundedCornersTransformation(16, 0))
|
||||
.into(holder.art)
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.github.apognu.otter.R
|
||||
import com.github.apognu.otter.fragments.FunkwhaleAdapter
|
||||
import com.github.apognu.otter.utils.Album
|
||||
import com.github.apognu.otter.utils.normalizeUrl
|
||||
import com.github.apognu.otter.utils.maybeLoad
|
||||
import com.github.apognu.otter.utils.maybeNormalizeUrl
|
||||
import com.squareup.picasso.Picasso
|
||||
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
|
||||
import kotlinx.android.synthetic.main.row_album_grid.view.*
|
||||
|
@ -32,7 +33,7 @@ class AlbumsGridAdapter(val context: Context?, private val listener: OnAlbumClic
|
|||
val album = data[position]
|
||||
|
||||
Picasso.get()
|
||||
.load(normalizeUrl(album.cover.original))
|
||||
.maybeLoad(maybeNormalizeUrl(album.cover.original))
|
||||
.fit()
|
||||
.placeholder(R.drawable.cover)
|
||||
.transform(RoundedCornersTransformation(24, 0))
|
||||
|
|
|
@ -8,7 +8,8 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.github.apognu.otter.R
|
||||
import com.github.apognu.otter.fragments.FunkwhaleAdapter
|
||||
import com.github.apognu.otter.utils.Artist
|
||||
import com.github.apognu.otter.utils.normalizeUrl
|
||||
import com.github.apognu.otter.utils.maybeLoad
|
||||
import com.github.apognu.otter.utils.maybeNormalizeUrl
|
||||
import com.squareup.picasso.Picasso
|
||||
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
|
||||
import kotlinx.android.synthetic.main.row_artist.view.*
|
||||
|
@ -36,9 +37,8 @@ class ArtistsAdapter(val context: Context?, private val listener: OnArtistClickL
|
|||
artist.albums?.let { albums ->
|
||||
if (albums.isNotEmpty()) {
|
||||
Picasso.get()
|
||||
.load(normalizeUrl(albums[0].cover.original))
|
||||
.maybeLoad(maybeNormalizeUrl(albums[0].cover.original))
|
||||
.fit()
|
||||
.placeholder(R.drawable.cover)
|
||||
.transform(RoundedCornersTransformation(16, 0))
|
||||
.into(holder.art)
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen
|
|||
val favorite = data[position]
|
||||
|
||||
Picasso.get()
|
||||
.load(normalizeUrl(favorite.track.album.cover.original))
|
||||
.maybeLoad(maybeNormalizeUrl(favorite.track.album.cover.original))
|
||||
.fit()
|
||||
.placeholder(R.drawable.cover)
|
||||
.transform(RoundedCornersTransformation(16, 0))
|
||||
|
|
|
@ -56,7 +56,7 @@ class PlaylistTracksAdapter(private val context: Context?, private val favoriteL
|
|||
val track = data[position]
|
||||
|
||||
Picasso.get()
|
||||
.load(normalizeUrl(track.track.album.cover.original))
|
||||
.maybeLoad(maybeNormalizeUrl(track.track.album.cover.original))
|
||||
.fit()
|
||||
.placeholder(R.drawable.cover)
|
||||
.transform(RoundedCornersTransformation(16, 0))
|
||||
|
|
|
@ -56,9 +56,8 @@ class TracksAdapter(private val context: Context?, private val favoriteListener:
|
|||
val track = data[position]
|
||||
|
||||
Picasso.get()
|
||||
.load(normalizeUrl(track.album.cover.original))
|
||||
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
|
||||
.fit()
|
||||
.placeholder(R.drawable.cover)
|
||||
.transform(RoundedCornersTransformation(16, 0))
|
||||
.into(holder.cover)
|
||||
|
||||
|
|
|
@ -11,9 +11,7 @@ import com.github.apognu.otter.R
|
|||
import com.github.apognu.otter.activities.MainActivity
|
||||
import com.github.apognu.otter.adapters.AlbumsAdapter
|
||||
import com.github.apognu.otter.repositories.AlbumsRepository
|
||||
import com.github.apognu.otter.utils.Album
|
||||
import com.github.apognu.otter.utils.AppContext
|
||||
import com.github.apognu.otter.utils.Artist
|
||||
import com.github.apognu.otter.utils.*
|
||||
import com.squareup.picasso.Picasso
|
||||
import kotlinx.android.synthetic.main.fragment_albums.*
|
||||
|
||||
|
@ -54,7 +52,7 @@ class AlbumsFragment : FunkwhaleFragment<Album, AlbumsAdapter>() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
Picasso.get()
|
||||
.load(artistArt)
|
||||
.maybeLoad(maybeNormalizeUrl(artistArt))
|
||||
.noFade()
|
||||
.fit()
|
||||
.centerCrop()
|
||||
|
|
|
@ -100,7 +100,7 @@ class PlaylistTracksFragment : FunkwhaleFragment<PlaylistTrack, PlaylistTracksAd
|
|||
}
|
||||
|
||||
Picasso.get()
|
||||
.load(normalizeUrl(url))
|
||||
.maybeLoad(maybeNormalizeUrl(url))
|
||||
.into(imageView)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ class TracksFragment : FunkwhaleFragment<Track, TracksAdapter>() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
Picasso.get()
|
||||
.load(albumCover)
|
||||
.maybeLoad(maybeNormalizeUrl(albumCover))
|
||||
.noFade()
|
||||
.fit()
|
||||
.centerCrop()
|
||||
|
|
|
@ -60,7 +60,12 @@ class MediaControlsManager(val context: Service, private val mediaSession: Media
|
|||
.setShowActionsInCompactView(0, 1, 2)
|
||||
)
|
||||
.setSmallIcon(R.drawable.ottericon)
|
||||
.setLargeIcon(Picasso.get().load(normalizeUrl(track.album.cover.original)).get())
|
||||
.run {
|
||||
val url = maybeNormalizeUrl(track.album.cover.original)
|
||||
|
||||
if (url != null) setLargeIcon(Picasso.get().load(url).get())
|
||||
else this
|
||||
}
|
||||
.setContentTitle(track.title)
|
||||
.setContentText(track.artist.name)
|
||||
.setContentIntent(openPendingIntent)
|
||||
|
|
|
@ -37,7 +37,7 @@ class QueueManager(val context: Context) {
|
|||
val factory = factory()
|
||||
|
||||
datasources.addMediaSources(metadata.map { track ->
|
||||
val url = normalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
|
||||
ProgressiveMediaSource.Factory(factory).setTag(track.title).createMediaSource(Uri.parse(url))
|
||||
})
|
||||
|
@ -73,7 +73,7 @@ class QueueManager(val context: Context) {
|
|||
val factory = factory()
|
||||
|
||||
val sources = tracks.map { track ->
|
||||
val url = normalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
|
||||
ProgressiveMediaSource.Factory(factory).setTag(track.title).createMediaSource(Uri.parse(url))
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ class QueueManager(val context: Context) {
|
|||
val tracks = tracks.filter { metadata.indexOf(it) == -1 }
|
||||
|
||||
val sources = tracks.map { track ->
|
||||
val url = normalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
|
||||
ProgressiveMediaSource.Factory(factory).createMediaSource(Uri.parse(url))
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ class QueueManager(val context: Context) {
|
|||
|
||||
fun insertNext(track: Track) {
|
||||
val factory = factory()
|
||||
val url = normalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
|
||||
if (metadata.indexOf(track) == -1) {
|
||||
ProgressiveMediaSource.Factory(factory).createMediaSource(Uri.parse(url)).let {
|
||||
|
|
|
@ -31,7 +31,7 @@ class FavoritesRepository(override val context: Context?) : Repository<Favorite,
|
|||
|
||||
runBlocking(IO) {
|
||||
Fuel
|
||||
.post(normalizeUrl("/api/v1/favorites/tracks"))
|
||||
.post(mustNormalizeUrl("/api/v1/favorites/tracks"))
|
||||
.header("Authorization", "Bearer $token")
|
||||
.header("Content-Type", "application/json")
|
||||
.body(Gson().toJson(body))
|
||||
|
@ -45,7 +45,7 @@ class FavoritesRepository(override val context: Context?) : Repository<Favorite,
|
|||
|
||||
runBlocking(IO) {
|
||||
Fuel
|
||||
.post(normalizeUrl("/api/v1/favorites/tracks/remove/"))
|
||||
.post(mustNormalizeUrl("/api/v1/favorites/tracks/remove/"))
|
||||
.header("Authorization", "Bearer $token")
|
||||
.header("Content-Type", "application/json")
|
||||
.body(Gson().toJson(body))
|
||||
|
|
|
@ -78,7 +78,7 @@ class HttpUpstream<D : Any, R : FunkwhaleResponse<D>>(private val behavior: Beha
|
|||
val token = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("access_token")
|
||||
|
||||
val (_, response, result) = Fuel
|
||||
.get(normalizeUrl(url))
|
||||
.get(mustNormalizeUrl(url))
|
||||
.header("Authorization", "Bearer $token")
|
||||
.awaitObjectResponseResult(GenericDeserializer<R>(type))
|
||||
|
||||
|
@ -94,7 +94,7 @@ class HttpUpstream<D : Any, R : FunkwhaleResponse<D>>(private val behavior: Beha
|
|||
val token = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("access_token")
|
||||
|
||||
Fuel
|
||||
.get(normalizeUrl(url))
|
||||
.get(mustNormalizeUrl(url))
|
||||
.header("Authorization", "Bearer $token")
|
||||
.awaitObjectResult(GenericDeserializer(type))
|
||||
} else {
|
||||
|
|
|
@ -23,7 +23,7 @@ object HTTP {
|
|||
"password" to PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("password")
|
||||
).toList()
|
||||
|
||||
val result = Fuel.post(normalizeUrl("/api/v1/token"), body).awaitObjectResult(gsonDeserializerOf(FwCredentials::class.java))
|
||||
val result = Fuel.post(mustNormalizeUrl("/api/v1/token"), body).awaitObjectResult(gsonDeserializerOf(FwCredentials::class.java))
|
||||
|
||||
return result.fold(
|
||||
{ data ->
|
||||
|
@ -39,7 +39,7 @@ object HTTP {
|
|||
val token = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("access_token")
|
||||
|
||||
val (_, response, result) = Fuel
|
||||
.get(normalizeUrl(url))
|
||||
.get(mustNormalizeUrl(url))
|
||||
.header("Authorization", "Bearer $token")
|
||||
.awaitObjectResponseResult(gsonDeserializerOf(T::class.java))
|
||||
|
||||
|
@ -55,7 +55,7 @@ object HTTP {
|
|||
val token = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("access_token")
|
||||
|
||||
Fuel
|
||||
.get(normalizeUrl(url))
|
||||
.get(mustNormalizeUrl(url))
|
||||
.header("Authorization", "Bearer $token")
|
||||
.awaitObjectResult(gsonDeserializerOf(T::class.java))
|
||||
} else {
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package com.github.apognu.otter.utils
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.github.apognu.otter.R
|
||||
import com.github.apognu.otter.fragments.BrowseFragment
|
||||
import com.github.apognu.otter.repositories.Repository
|
||||
import com.squareup.picasso.Picasso
|
||||
import com.squareup.picasso.RequestCreator
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
|
@ -73,4 +77,9 @@ fun <T> T.applyOnApi(api: Int, block: T.() -> T): T {
|
|||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
fun Picasso.maybeLoad(url: String?): RequestCreator {
|
||||
if (url == null) return load(R.drawable.cover)
|
||||
else return load(url)
|
||||
}
|
|
@ -16,7 +16,18 @@ fun Any.log(message: String) {
|
|||
Log.d("FUNKWHALE", "${this.javaClass.simpleName}: $message")
|
||||
}
|
||||
|
||||
fun normalizeUrl(url: String): String {
|
||||
fun maybeNormalizeUrl(url: String?): String? {
|
||||
if (url == null || url.isEmpty()) return null
|
||||
|
||||
val fallbackHost = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("hostname")
|
||||
val uri = URI(url).takeIf { it.host != null } ?: URI("$fallbackHost$url")
|
||||
|
||||
return uri.run {
|
||||
URI("https", host, path, query, null)
|
||||
}.toString()
|
||||
}
|
||||
|
||||
fun mustNormalizeUrl(url: String): String {
|
||||
val fallbackHost = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("hostname")
|
||||
val uri = URI(url).takeIf { it.host != null } ?: URI("$fallbackHost$url")
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo 'Usage: ./publish.sh <TAG> <MESSAGE>' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$(git diff --stat)" != '' ]; then
|
||||
echo 'ERROR: repository is dirty.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TAG="$1"
|
||||
MESSAGE="$2"
|
||||
|
||||
if [ "$(git tag -l | grep $TAG)" != '' ]; then
|
||||
echo "ERROR: tag $TAG already exists." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git tag -a -m "$MESSAGE" "$TAG"
|
||||
git push --tags
|
||||
|
||||
./gradlew publish
|
||||
|
Loading…
Reference in New Issue