Browse Source

Added support for native radios (random and less listened to radios). Advancing #8.

housekeeping/remove-warnings
Antoine POPINEAU 4 years ago
parent
commit
dc7803acb4
No known key found for this signature in database
GPG Key ID: A78AC64694F84063
  1. 18
      app/src/main/java/com/github/apognu/otter/adapters/RadiosAdapter.kt
  2. 58
      app/src/main/java/com/github/apognu/otter/playback/RadioPlayer.kt
  3. 15
      app/src/main/java/com/github/apognu/otter/repositories/RadiosRepository.kt
  4. 1
      app/src/main/java/com/github/apognu/otter/utils/Models.kt
  5. 15
      app/src/main/res/drawable/sad.xml
  6. 4
      app/src/main/res/values-fr/strings.xml
  7. 4
      app/src/main/res/values/strings.xml

18
app/src/main/java/com/github/apognu/otter/adapters/RadiosAdapter.kt

@ -32,9 +32,25 @@ class RadiosAdapter(val context: Context?, private val listener: OnRadioClickLis @@ -32,9 +32,25 @@ class RadiosAdapter(val context: Context?, private val listener: OnRadioClickLis
holder.name.text = radio.name
holder.description.text = radio.description
context?.let { context ->
when (radio.radio_type) {
"random" -> {
holder.art.setImageDrawable(context.getDrawable(R.drawable.shuffle))
holder.art.alpha = 0.7f
holder.art.setColorFilter(context.getColor(R.color.controlForeground))
}
"less-listened" -> {
holder.art.setImageDrawable(context.getDrawable(R.drawable.sad))
holder.art.alpha = 0.7f
holder.art.setColorFilter(context.getColor(R.color.controlForeground))
}
}
}
}
inner class ViewHolder(view: View, val listener: OnRadioClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener {
inner class ViewHolder(view: View, private val listener: OnRadioClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener {
val art = view.art
val name = view.name
val description = view.description

58
app/src/main/java/com/github/apognu/otter/playback/RadioPlayer.kt

@ -18,7 +18,7 @@ import kotlinx.coroutines.launch @@ -18,7 +18,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.withContext
data class RadioSessionBody(val radio_type: String, val custom_radio: Int)
data class RadioSessionBody(val radio_type: String, var custom_radio: Int? = null)
data class RadioSession(val id: Int)
data class RadioTrackBody(val session: Int)
data class RadioTrack(val position: Int, val track: RadioTrackID)
@ -33,10 +33,12 @@ class RadioPlayer(val context: Context) { @@ -33,10 +33,12 @@ class RadioPlayer(val context: Context) {
private val favoritedRepository = FavoritedRepository(context)
init {
Cache.get(context, "radio_id")?.readLine()?.toInt()?.let { radio_id ->
Cache.get(context, "radio_session")?.readLine()?.toInt()?.let { radio_session ->
currentRadio = Radio(radio_id, "", "")
session = radio_session
Cache.get(context, "radio_type")?.readLine()?.let { radio_type ->
Cache.get(context, "radio_id")?.readLine()?.toInt()?.let { radio_id ->
Cache.get(context, "radio_session")?.readLine()?.toInt()?.let { radio_session ->
currentRadio = Radio(radio_id, radio_type, "", "")
session = radio_session
}
}
}
}
@ -54,6 +56,7 @@ class RadioPlayer(val context: Context) { @@ -54,6 +56,7 @@ class RadioPlayer(val context: Context) {
currentRadio = null
session = null
Cache.delete(context, "radio_type")
Cache.delete(context, "radio_id")
Cache.delete(context, "radio_session")
}
@ -61,27 +64,34 @@ class RadioPlayer(val context: Context) { @@ -61,27 +64,34 @@ class RadioPlayer(val context: Context) {
fun isActive() = currentRadio != null && session != null
private suspend fun createSession() {
currentRadio?.let { radio ->
try {
val body = Gson().toJson(RadioSessionBody("custom", radio.id))
val result = Fuel.post(mustNormalizeUrl("/api/v1/radios/sessions/"))
.authorize()
.header("Content-Type", "application/json")
.body(body)
.awaitObjectResult(gsonDeserializerOf(RadioSession::class.java))
session = result.get().id
Cache.set(context, "radio_id", radio.id.toString().toByteArray())
Cache.set(context, "radio_session", session.toString().toByteArray())
prepareNextTrack(true)
} catch (e: Exception) {
withContext(Main) {
context.toast(context.getString(R.string.radio_playback_error))
currentRadio?.let { radio ->
try {
val request = RadioSessionBody(radio.radio_type).apply {
if (radio_type == "custom") {
custom_radio = radio.id
}
}
val body = Gson().toJson(request)
val result = Fuel.post(mustNormalizeUrl("/api/v1/radios/sessions/"))
.authorize()
.header("Content-Type", "application/json")
.body(body)
.awaitObjectResult(gsonDeserializerOf(RadioSession::class.java))
session = result.get().id
Cache.set(context, "radio_type", radio.radio_type.toByteArray())
Cache.set(context, "radio_id", radio.id.toString().toByteArray())
Cache.set(context, "radio_session", session.toString().toByteArray())
prepareNextTrack(true)
} catch (e: Exception) {
withContext(Main) {
context.toast(context.getString(R.string.radio_playback_error))
}
}
}
}
suspend fun prepareNextTrack(first: Boolean = false) {
@ -98,7 +108,7 @@ class RadioPlayer(val context: Context) { @@ -98,7 +108,7 @@ class RadioPlayer(val context: Context) {
.authorize()
.awaitObjectResult(gsonDeserializerOf(Track::class.java))
val favorites = FavoritedRepository(context).fetch(Repository.Origin.Network.origin)
val favorites = favoritedRepository.fetch(Repository.Origin.Network.origin)
.map { it.data }
.toList()
.flatten()

15
app/src/main/java/com/github/apognu/otter/repositories/RadiosRepository.kt

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
package com.github.apognu.otter.repositories
import android.content.Context
import com.github.apognu.otter.R
import com.github.apognu.otter.utils.FunkwhaleResponse
import com.github.apognu.otter.utils.Radio
import com.github.apognu.otter.utils.RadiosCache
@ -15,4 +16,18 @@ class RadiosRepository(override val context: Context?) : Repository<Radio, Radio @@ -15,4 +16,18 @@ class RadiosRepository(override val context: Context?) : Repository<Radio, Radio
override fun cache(data: List<Radio>) = RadiosCache(data)
override fun uncache(reader: BufferedReader) = gsonDeserializerOf(RadiosCache::class.java).deserialize(reader)
override fun onDataFetched(data: List<Radio>): List<Radio> {
return data
.map { radio ->
radio.apply { radio_type = "custom" }
}
.toMutableList()
.apply {
context?.let { context ->
add(0, Radio(0, "random", context.getString(R.string.radio_random_title), context.getString(R.string.radio_random_description)))
add(1, Radio(0, "less-listened", context.getString(R.string.radio_less_listened_title), context.getString(R.string.radio_less_listened_description)))
}
}
}
}

1
app/src/main/java/com/github/apognu/otter/utils/Models.kt

@ -142,6 +142,7 @@ data class PlaylistTrack(val track: Track) @@ -142,6 +142,7 @@ data class PlaylistTrack(val track: Track)
data class Radio(
val id: Int,
var radio_type: String,
val name: String,
val description: String
)

15
app/src/main/res/drawable/sad.xml

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M15.5,9.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
<path
android:fillColor="#FF000000"
android:pathData="M8.5,9.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
<path
android:fillColor="#FF000000"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM12,14c-2.33,0 -4.32,1.45 -5.12,3.5h1.67c0.69,-1.19 1.97,-2 3.45,-2s2.75,0.81 3.45,2h1.67c-0.8,-2.05 -2.79,-3.5 -5.12,-3.5z"/>
</vector>

4
app/src/main/res/values-fr/strings.xml

@ -101,6 +101,10 @@ @@ -101,6 +101,10 @@
<string name="track_info_details_track_instance">Instance Funkwhale</string>
<string name="radio_playback_error">Une erreur s\'est produite lors de la lecture de cette radio</string>
<string name="radio_random_title">Aléatoire</string>
<string name="radio_random_description">Choix de pistes totalement aléatoires, vous découvrirez peut-être quelque chose ?</string>
<string name="radio_less_listened_title">Moins écoutées</string>
<string name="radio_less_listened_description">Découvrez les morceaux que vous n\'écoutez généralement pas. Il est temps de rétablir un équilibre.</string>
<string name="logout_title">Déconnexion</string>
<string name="logout_content">Etes-vous certains de vouloir vous déconnecter de votre instance Funkwhale ?</string>

4
app/src/main/res/values/strings.xml

@ -101,6 +101,10 @@ @@ -101,6 +101,10 @@
<string name="track_info_details_track_instance">Funkwhale instance</string>
<string name="radio_playback_error">There was an error while trying to play this radio</string>
<string name="radio_random_title">Random</string>
<string name="radio_random_description">Totally random picks, maybe you\'ll discover new things?</string>
<string name="radio_less_listened_title">Less listened</string>
<string name="radio_less_listened_description">Listen to tracks you usually don\'t. It\'s time to restore some balance.</string>
<string name="logout_title">Sign out</string>
<string name="logout_content">Are you sure you want to sign out of your Funkwhale instance?</string>

Loading…
Cancel
Save