Browse Source

Fixed crash on coverless albums.

housekeeping/remove-warnings
Antoine POPINEAU 5 years ago
parent
commit
78468167ca
No known key found for this signature in database
GPG Key ID: A78AC64694F84063
  1. 4
      app/src/main/java/com/github/apognu/otter/activities/MainActivity.kt
  2. 6
      app/src/main/java/com/github/apognu/otter/adapters/AlbumsAdapter.kt
  3. 5
      app/src/main/java/com/github/apognu/otter/adapters/AlbumsGridAdapter.kt
  4. 6
      app/src/main/java/com/github/apognu/otter/adapters/ArtistsAdapter.kt
  5. 2
      app/src/main/java/com/github/apognu/otter/adapters/FavoritesAdapter.kt
  6. 2
      app/src/main/java/com/github/apognu/otter/adapters/PlaylistTracksAdapter.kt
  7. 3
      app/src/main/java/com/github/apognu/otter/adapters/TracksAdapter.kt
  8. 6
      app/src/main/java/com/github/apognu/otter/fragments/AlbumsFragment.kt
  9. 2
      app/src/main/java/com/github/apognu/otter/fragments/PlaylistTracksFragment.kt
  10. 2
      app/src/main/java/com/github/apognu/otter/fragments/TracksFragment.kt
  11. 7
      app/src/main/java/com/github/apognu/otter/playback/MediaControlsManager.kt
  12. 8
      app/src/main/java/com/github/apognu/otter/playback/QueueManager.kt
  13. 4
      app/src/main/java/com/github/apognu/otter/repositories/FavoritesRepository.kt
  14. 4
      app/src/main/java/com/github/apognu/otter/repositories/HttpUpstream.kt
  15. 6
      app/src/main/java/com/github/apognu/otter/utils/Data.kt
  16. 9
      app/src/main/java/com/github/apognu/otter/utils/Extensions.kt
  17. 13
      app/src/main/java/com/github/apognu/otter/utils/Util.kt
  18. 25
      publish.sh

4
app/src/main/java/com/github/apognu/otter/activities/MainActivity.kt

@ -224,13 +224,13 @@ class MainActivity : AppCompatActivity() {
now_playing_details_progress.progress = 0 now_playing_details_progress.progress = 0
Picasso.get() Picasso.get()
.load(normalizeUrl(track.album.cover.original)) .maybeLoad(maybeNormalizeUrl(track.album.cover.original))
.fit() .fit()
.centerCrop() .centerCrop()
.into(now_playing_cover) .into(now_playing_cover)
Picasso.get() Picasso.get()
.load(normalizeUrl(track.album.cover.original)) .maybeLoad(maybeNormalizeUrl(track.album.cover.original))
.fit() .fit()
.centerCrop() .centerCrop()
.into(now_playing_details_cover) .into(now_playing_details_cover)

6
app/src/main/java/com/github/apognu/otter/adapters/AlbumsAdapter.kt

@ -8,7 +8,8 @@ import androidx.recyclerview.widget.RecyclerView
import com.github.apognu.otter.R import com.github.apognu.otter.R
import com.github.apognu.otter.fragments.FunkwhaleAdapter import com.github.apognu.otter.fragments.FunkwhaleAdapter
import com.github.apognu.otter.utils.Album 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 com.squareup.picasso.Picasso
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
import kotlinx.android.synthetic.main.row_album.view.* import kotlinx.android.synthetic.main.row_album.view.*
@ -33,9 +34,8 @@ class AlbumsAdapter(val context: Context?, val listener: OnAlbumClickListener) :
val album = data[position] val album = data[position]
Picasso.get() Picasso.get()
.load(normalizeUrl(album.cover.original)) .maybeLoad(maybeNormalizeUrl(album.cover.original))
.fit() .fit()
.placeholder(R.drawable.cover)
.transform(RoundedCornersTransformation(16, 0)) .transform(RoundedCornersTransformation(16, 0))
.into(holder.art) .into(holder.art)

5
app/src/main/java/com/github/apognu/otter/adapters/AlbumsGridAdapter.kt

@ -8,7 +8,8 @@ import androidx.recyclerview.widget.RecyclerView
import com.github.apognu.otter.R import com.github.apognu.otter.R
import com.github.apognu.otter.fragments.FunkwhaleAdapter import com.github.apognu.otter.fragments.FunkwhaleAdapter
import com.github.apognu.otter.utils.Album 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 com.squareup.picasso.Picasso
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
import kotlinx.android.synthetic.main.row_album_grid.view.* 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] val album = data[position]
Picasso.get() Picasso.get()
.load(normalizeUrl(album.cover.original)) .maybeLoad(maybeNormalizeUrl(album.cover.original))
.fit() .fit()
.placeholder(R.drawable.cover) .placeholder(R.drawable.cover)
.transform(RoundedCornersTransformation(24, 0)) .transform(RoundedCornersTransformation(24, 0))

6
app/src/main/java/com/github/apognu/otter/adapters/ArtistsAdapter.kt

@ -8,7 +8,8 @@ import androidx.recyclerview.widget.RecyclerView
import com.github.apognu.otter.R import com.github.apognu.otter.R
import com.github.apognu.otter.fragments.FunkwhaleAdapter import com.github.apognu.otter.fragments.FunkwhaleAdapter
import com.github.apognu.otter.utils.Artist 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 com.squareup.picasso.Picasso
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
import kotlinx.android.synthetic.main.row_artist.view.* 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 -> artist.albums?.let { albums ->
if (albums.isNotEmpty()) { if (albums.isNotEmpty()) {
Picasso.get() Picasso.get()
.load(normalizeUrl(albums[0].cover.original)) .maybeLoad(maybeNormalizeUrl(albums[0].cover.original))
.fit() .fit()
.placeholder(R.drawable.cover)
.transform(RoundedCornersTransformation(16, 0)) .transform(RoundedCornersTransformation(16, 0))
.into(holder.art) .into(holder.art)
} }

2
app/src/main/java/com/github/apognu/otter/adapters/FavoritesAdapter.kt

@ -44,7 +44,7 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen
val favorite = data[position] val favorite = data[position]
Picasso.get() Picasso.get()
.load(normalizeUrl(favorite.track.album.cover.original)) .maybeLoad(maybeNormalizeUrl(favorite.track.album.cover.original))
.fit() .fit()
.placeholder(R.drawable.cover) .placeholder(R.drawable.cover)
.transform(RoundedCornersTransformation(16, 0)) .transform(RoundedCornersTransformation(16, 0))

2
app/src/main/java/com/github/apognu/otter/adapters/PlaylistTracksAdapter.kt

@ -56,7 +56,7 @@ class PlaylistTracksAdapter(private val context: Context?, private val favoriteL
val track = data[position] val track = data[position]
Picasso.get() Picasso.get()
.load(normalizeUrl(track.track.album.cover.original)) .maybeLoad(maybeNormalizeUrl(track.track.album.cover.original))
.fit() .fit()
.placeholder(R.drawable.cover) .placeholder(R.drawable.cover)
.transform(RoundedCornersTransformation(16, 0)) .transform(RoundedCornersTransformation(16, 0))

3
app/src/main/java/com/github/apognu/otter/adapters/TracksAdapter.kt

@ -56,9 +56,8 @@ class TracksAdapter(private val context: Context?, private val favoriteListener:
val track = data[position] val track = data[position]
Picasso.get() Picasso.get()
.load(normalizeUrl(track.album.cover.original)) .maybeLoad(maybeNormalizeUrl(track.album.cover.original))
.fit() .fit()
.placeholder(R.drawable.cover)
.transform(RoundedCornersTransformation(16, 0)) .transform(RoundedCornersTransformation(16, 0))
.into(holder.cover) .into(holder.cover)

6
app/src/main/java/com/github/apognu/otter/fragments/AlbumsFragment.kt

@ -11,9 +11,7 @@ import com.github.apognu.otter.R
import com.github.apognu.otter.activities.MainActivity import com.github.apognu.otter.activities.MainActivity
import com.github.apognu.otter.adapters.AlbumsAdapter import com.github.apognu.otter.adapters.AlbumsAdapter
import com.github.apognu.otter.repositories.AlbumsRepository import com.github.apognu.otter.repositories.AlbumsRepository
import com.github.apognu.otter.utils.Album import com.github.apognu.otter.utils.*
import com.github.apognu.otter.utils.AppContext
import com.github.apognu.otter.utils.Artist
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.fragment_albums.* import kotlinx.android.synthetic.main.fragment_albums.*
@ -54,7 +52,7 @@ class AlbumsFragment : FunkwhaleFragment<Album, AlbumsAdapter>() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
Picasso.get() Picasso.get()
.load(artistArt) .maybeLoad(maybeNormalizeUrl(artistArt))
.noFade() .noFade()
.fit() .fit()
.centerCrop() .centerCrop()

2
app/src/main/java/com/github/apognu/otter/fragments/PlaylistTracksFragment.kt

@ -100,7 +100,7 @@ class PlaylistTracksFragment : FunkwhaleFragment<PlaylistTrack, PlaylistTracksAd
} }
Picasso.get() Picasso.get()
.load(normalizeUrl(url)) .maybeLoad(maybeNormalizeUrl(url))
.into(imageView) .into(imageView)
} }
} }

2
app/src/main/java/com/github/apognu/otter/fragments/TracksFragment.kt

@ -60,7 +60,7 @@ class TracksFragment : FunkwhaleFragment<Track, TracksAdapter>() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
Picasso.get() Picasso.get()
.load(albumCover) .maybeLoad(maybeNormalizeUrl(albumCover))
.noFade() .noFade()
.fit() .fit()
.centerCrop() .centerCrop()

7
app/src/main/java/com/github/apognu/otter/playback/MediaControlsManager.kt

@ -60,7 +60,12 @@ class MediaControlsManager(val context: Service, private val mediaSession: Media
.setShowActionsInCompactView(0, 1, 2) .setShowActionsInCompactView(0, 1, 2)
) )
.setSmallIcon(R.drawable.ottericon) .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) .setContentTitle(track.title)
.setContentText(track.artist.name) .setContentText(track.artist.name)
.setContentIntent(openPendingIntent) .setContentIntent(openPendingIntent)

8
app/src/main/java/com/github/apognu/otter/playback/QueueManager.kt

@ -37,7 +37,7 @@ class QueueManager(val context: Context) {
val factory = factory() val factory = factory()
datasources.addMediaSources(metadata.map { track -> 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)) ProgressiveMediaSource.Factory(factory).setTag(track.title).createMediaSource(Uri.parse(url))
}) })
@ -73,7 +73,7 @@ class QueueManager(val context: Context) {
val factory = factory() val factory = factory()
val sources = tracks.map { track -> 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)) 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 tracks = tracks.filter { metadata.indexOf(it) == -1 }
val sources = tracks.map { track -> 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)) ProgressiveMediaSource.Factory(factory).createMediaSource(Uri.parse(url))
} }
@ -107,7 +107,7 @@ class QueueManager(val context: Context) {
fun insertNext(track: Track) { fun insertNext(track: Track) {
val factory = factory() val factory = factory()
val url = normalizeUrl(track.bestUpload()?.listen_url ?: "") val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
if (metadata.indexOf(track) == -1) { if (metadata.indexOf(track) == -1) {
ProgressiveMediaSource.Factory(factory).createMediaSource(Uri.parse(url)).let { ProgressiveMediaSource.Factory(factory).createMediaSource(Uri.parse(url)).let {

4
app/src/main/java/com/github/apognu/otter/repositories/FavoritesRepository.kt

@ -31,7 +31,7 @@ class FavoritesRepository(override val context: Context?) : Repository<Favorite,
runBlocking(IO) { runBlocking(IO) {
Fuel Fuel
.post(normalizeUrl("/api/v1/favorites/tracks")) .post(mustNormalizeUrl("/api/v1/favorites/tracks"))
.header("Authorization", "Bearer $token") .header("Authorization", "Bearer $token")
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.body(Gson().toJson(body)) .body(Gson().toJson(body))
@ -45,7 +45,7 @@ class FavoritesRepository(override val context: Context?) : Repository<Favorite,
runBlocking(IO) { runBlocking(IO) {
Fuel Fuel
.post(normalizeUrl("/api/v1/favorites/tracks/remove/")) .post(mustNormalizeUrl("/api/v1/favorites/tracks/remove/"))
.header("Authorization", "Bearer $token") .header("Authorization", "Bearer $token")
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.body(Gson().toJson(body)) .body(Gson().toJson(body))

4
app/src/main/java/com/github/apognu/otter/repositories/HttpUpstream.kt

@ -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 token = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("access_token")
val (_, response, result) = Fuel val (_, response, result) = Fuel
.get(normalizeUrl(url)) .get(mustNormalizeUrl(url))
.header("Authorization", "Bearer $token") .header("Authorization", "Bearer $token")
.awaitObjectResponseResult(GenericDeserializer<R>(type)) .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") val token = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("access_token")
Fuel Fuel
.get(normalizeUrl(url)) .get(mustNormalizeUrl(url))
.header("Authorization", "Bearer $token") .header("Authorization", "Bearer $token")
.awaitObjectResult(GenericDeserializer(type)) .awaitObjectResult(GenericDeserializer(type))
} else { } else {

6
app/src/main/java/com/github/apognu/otter/utils/Data.kt

@ -23,7 +23,7 @@ object HTTP {
"password" to PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("password") "password" to PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("password")
).toList() ).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( return result.fold(
{ data -> { data ->
@ -39,7 +39,7 @@ object HTTP {
val token = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("access_token") val token = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("access_token")
val (_, response, result) = Fuel val (_, response, result) = Fuel
.get(normalizeUrl(url)) .get(mustNormalizeUrl(url))
.header("Authorization", "Bearer $token") .header("Authorization", "Bearer $token")
.awaitObjectResponseResult(gsonDeserializerOf(T::class.java)) .awaitObjectResponseResult(gsonDeserializerOf(T::class.java))
@ -55,7 +55,7 @@ object HTTP {
val token = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("access_token") val token = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("access_token")
Fuel Fuel
.get(normalizeUrl(url)) .get(mustNormalizeUrl(url))
.header("Authorization", "Bearer $token") .header("Authorization", "Bearer $token")
.awaitObjectResult(gsonDeserializerOf(T::class.java)) .awaitObjectResult(gsonDeserializerOf(T::class.java))
} else { } else {

9
app/src/main/java/com/github/apognu/otter/utils/Extensions.kt

@ -1,11 +1,15 @@
package com.github.apognu.otter.utils package com.github.apognu.otter.utils
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.github.apognu.otter.R
import com.github.apognu.otter.fragments.BrowseFragment import com.github.apognu.otter.fragments.BrowseFragment
import com.github.apognu.otter.repositories.Repository 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.Dispatchers.Main
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
@ -73,4 +77,9 @@ fun <T> T.applyOnApi(api: Int, block: T.() -> T): T {
} else { } else {
this this
} }
}
fun Picasso.maybeLoad(url: String?): RequestCreator {
if (url == null) return load(R.drawable.cover)
else return load(url)
} }

13
app/src/main/java/com/github/apognu/otter/utils/Util.kt

@ -16,7 +16,18 @@ fun Any.log(message: String) {
Log.d("FUNKWHALE", "${this.javaClass.simpleName}: $message") 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 fallbackHost = PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).getString("hostname")
val uri = URI(url).takeIf { it.host != null } ?: URI("$fallbackHost$url") val uri = URI(url).takeIf { it.host != null } ?: URI("$fallbackHost$url")

25
publish.sh

@ -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…
Cancel
Save