Upgrade to Kotlin 1.7.0

This commit is contained in:
Ryan Harg 2022-08-26 12:06:41 +00:00
parent 2d449549b0
commit bfdac03d0c
19 changed files with 204 additions and 207 deletions

View File

@ -153,7 +153,7 @@ play {
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.21")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")

View File

@ -326,77 +326,67 @@ class MainActivity : AppCompatActivity() {
@SuppressLint("NewApi")
private fun watchEventBus() {
lifecycleScope.launch(Main) {
EventBus.get().collect { message ->
when (message) {
is Event.LogOut -> {
FFA.get().deleteAllData(this@MainActivity)
startActivity(
Intent(this@MainActivity, LoginActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NO_HISTORY
}
)
finish()
}
is Event.PlaybackError -> toast(message.message)
is Event.Buffering -> {
when (message.value) {
true -> binding.nowPlayingContainer?.nowPlayingBuffering?.visibility = View.VISIBLE
false -> binding.nowPlayingContainer?.nowPlayingBuffering?.visibility = View.GONE
EventBus.get().collect { event ->
if (event is Event.LogOut) {
FFA.get().deleteAllData(this@MainActivity)
startActivity(
Intent(this@MainActivity, LoginActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NO_HISTORY
}
}
)
is Event.PlaybackStopped -> {
if (binding.nowPlaying.visibility == View.VISIBLE) {
(binding.container.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
finish()
} else if (event is Event.PlaybackError) {
toast(event.message)
} else if (event is Event.Buffering) {
when (event.value) {
true -> binding.nowPlayingContainer?.nowPlayingBuffering?.visibility = View.VISIBLE
false -> binding.nowPlayingContainer?.nowPlayingBuffering?.visibility = View.GONE
}
} else if (event is Event.PlaybackStopped) {
if (binding.nowPlaying.visibility == View.VISIBLE) {
(binding.container.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
it.bottomMargin = it.bottomMargin / 2
}
binding.landscapeQueue?.let { landscape_queue ->
(landscape_queue.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
it.bottomMargin = it.bottomMargin / 2
}
}
binding.landscapeQueue?.let { landscape_queue ->
(landscape_queue.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
it.bottomMargin = it.bottomMargin / 2
binding.nowPlaying.animate()
.alpha(0.0f)
.setDuration(400)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animator: Animator?) {
binding.nowPlaying.visibility = View.GONE
}
}
})
.start()
}
} else if (event is Event.TrackFinished) {
incrementListenCount(event.track)
} else if (event is Event.StateChanged) {
when (event.playing) {
true -> {
binding.nowPlayingContainer?.nowPlayingToggle?.icon = getDrawable(R.drawable.pause)
binding.nowPlayingContainer?.nowPlayingDetailsToggle?.icon =
getDrawable(R.drawable.pause)
}
binding.nowPlaying.animate()
.alpha(0.0f)
.setDuration(400)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animator: Animator?) {
binding.nowPlaying.visibility = View.GONE
}
})
.start()
false -> {
binding.nowPlayingContainer?.nowPlayingToggle?.icon = getDrawable(R.drawable.play)
binding.nowPlayingContainer?.nowPlayingDetailsToggle?.icon =
getDrawable(R.drawable.play)
}
}
is Event.TrackFinished -> incrementListenCount(message.track)
is Event.StateChanged -> {
when (message.playing) {
true -> {
binding.nowPlayingContainer?.nowPlayingToggle?.icon = getDrawable(R.drawable.pause)
binding.nowPlayingContainer?.nowPlayingDetailsToggle?.icon =
getDrawable(R.drawable.pause)
}
false -> {
binding.nowPlayingContainer?.nowPlayingToggle?.icon = getDrawable(R.drawable.play)
binding.nowPlayingContainer?.nowPlayingDetailsToggle?.icon =
getDrawable(R.drawable.play)
}
}
}
is Event.QueueChanged -> {
findViewById<View>(R.id.nav_queue)?.let { view ->
ObjectAnimator.ofFloat(view, View.ROTATION, 0f, 360f).let {
it.duration = 500
it.interpolator = AccelerateDecelerateInterpolator()
it.start()
}
} else if (event is Event.QueueChanged) {
findViewById<View>(R.id.nav_queue)?.let { view ->
ObjectAnimator.ofFloat(view, View.ROTATION, 0f, 360f).let {
it.duration = 500
it.interpolator = AccelerateDecelerateInterpolator()
it.start()
}
}
}
@ -405,32 +395,30 @@ class MainActivity : AppCompatActivity() {
lifecycleScope.launch(Main) {
CommandBus.get().collect { command ->
when (command) {
is Command.StartService -> {
Build.VERSION_CODES.O.onApi(
{
startForegroundService(
Intent(
this@MainActivity,
PlayerService::class.java
).apply {
putExtra(PlayerService.INITIAL_COMMAND_KEY, command.command.toString())
}
)
},
{
startService(
Intent(this@MainActivity, PlayerService::class.java).apply {
putExtra(PlayerService.INITIAL_COMMAND_KEY, command.command.toString())
}
)
}
)
}
is Command.RefreshTrack -> refreshCurrentTrack(command.track)
is Command.AddToPlaylist -> if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
if (command is Command.StartService) {
Build.VERSION_CODES.O.onApi(
{
startForegroundService(
Intent(
this@MainActivity,
PlayerService::class.java
).apply {
putExtra(PlayerService.INITIAL_COMMAND_KEY, command.command.toString())
}
)
},
{
startService(
Intent(this@MainActivity, PlayerService::class.java).apply {
putExtra(PlayerService.INITIAL_COMMAND_KEY, command.command.toString())
}
)
}
)
} else if (command is Command.RefreshTrack) {
refreshCurrentTrack(command.track)
} else if (command is Command.AddToPlaylist) {
if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
AddToPlaylistDialog.show(
layoutInflater,
this@MainActivity,

View File

@ -28,7 +28,6 @@ import audio.funkwhale.ffa.utils.getMetadata
import audio.funkwhale.ffa.utils.untilNetwork
import com.google.android.exoplayer2.offline.Download
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.net.URLEncoder
@ -65,8 +64,9 @@ class SearchActivity : AppCompatActivity() {
lifecycleScope.launch(Dispatchers.Main) {
CommandBus.get().collect { command ->
when (command) {
is Command.AddToPlaylist -> if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
if (command is Command.AddToPlaylist) {
if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
AddToPlaylistDialog.show(
layoutInflater,
this@SearchActivity,
@ -79,10 +79,8 @@ class SearchActivity : AppCompatActivity() {
}
lifecycleScope.launch(Dispatchers.IO) {
EventBus.get().collect { message ->
when (message) {
is Event.DownloadChanged -> refreshDownloadedTrack(message.download)
}
EventBus.get().collect { event ->
if (event is Event.DownloadChanged) refreshDownloadedTrack(event.download)
}
}

View File

@ -17,7 +17,6 @@ import audio.funkwhale.ffa.views.LoadingImageView
import com.preference.PowerPreference
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
class RadiosAdapter(
@ -190,12 +189,10 @@ class RadiosAdapter(
art.setColorFilter(context.getColor(R.color.controlForeground))
scope.launch(Main) {
EventBus.get().collect { message ->
when (message) {
is Event.RadioStarted -> {
art.colorFilter = originalColorFilter
LoadingImageView.stop(context, originalDrawable, art, imageAnimator)
}
EventBus.get().collect { event ->
if (event is Event.RadioStarted) {
art.colorFilter = originalColorFilter
LoadingImageView.stop(context, originalDrawable, art, imageAnimator)
}
}
}

View File

@ -25,7 +25,6 @@ import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadManager
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.java.KoinJavaComponent.inject
@ -84,18 +83,14 @@ class FavoritesFragment : FFAFragment<Track, FavoritesAdapter>() {
private fun watchEventBus() {
lifecycleScope.launch(Main) {
EventBus.get().collect { message ->
when (message) {
is Event.DownloadChanged -> refreshDownloadedTrack(message.download)
}
EventBus.get().collect { event ->
if (event is Event.DownloadChanged) refreshDownloadedTrack(event.download)
}
}
lifecycleScope.launch(Main) {
CommandBus.get().collect { command ->
when (command) {
is Command.RefreshTrack -> refreshCurrentTrack(command.track)
}
if (command is Command.RefreshTrack) refreshCurrentTrack(command.track)
}
}
}

View File

@ -110,17 +110,13 @@ class LandscapeQueueFragment : Fragment() {
private fun watchEventBus() {
activity?.lifecycleScope?.launch(Main) {
EventBus.get().collect { message ->
when (message) {
is Event.QueueChanged -> refresh()
}
if (message is Event.QueueChanged) refresh()
}
}
activity?.lifecycleScope?.launch(Main) {
CommandBus.get().collect { command ->
when (command) {
is Command.RefreshTrack -> refresh()
}
if (command is Command.RefreshTrack) refresh()
}
}
}

View File

@ -75,7 +75,12 @@ class PlaylistTracksFragment : FFAFragment<PlaylistTrack, PlaylistTracksAdapter>
favoritesRepository = FavoritesRepository(context)
playlistsRepository = ManagementPlaylistsRepository(context)
adapter = PlaylistTracksAdapter(layoutInflater, context, FavoriteListener(favoritesRepository), PlaylistListener())
adapter = PlaylistTracksAdapter(
layoutInflater,
context,
FavoriteListener(favoritesRepository),
PlaylistListener()
)
repository = PlaylistTracksRepository(context, albumId)
watchEventBus()
@ -199,8 +204,8 @@ class PlaylistTracksFragment : FFAFragment<PlaylistTrack, PlaylistTracksAdapter>
private fun watchEventBus() {
lifecycleScope.launch(Main) {
CommandBus.get().collect { command ->
when (command) {
is Command.RefreshTrack -> refreshCurrentTrack(command.track)
if (command is Command.RefreshTrack) {
refreshCurrentTrack(command.track)
}
}
}

View File

@ -127,16 +127,16 @@ class QueueFragment : BottomSheetDialogFragment() {
private fun watchEventBus() {
lifecycleScope.launch(Main) {
EventBus.get().collect { message ->
when (message) {
is Event.QueueChanged -> refresh()
if (message is Event.QueueChanged) {
refresh()
}
}
}
lifecycleScope.launch(Main) {
CommandBus.get().collect { command ->
when (command) {
is Command.RefreshTrack -> refresh()
if (command is Command.RefreshTrack) {
refresh()
}
}
}

View File

@ -62,12 +62,11 @@ class RadiosFragment : FFAFragment<Radio, RadiosAdapter>() {
lifecycleScope.launch(Main) {
EventBus.get().collect { message ->
when (message) {
is Event.RadioStarted ->
recycler.forEach {
it.isEnabled = true
it.isClickable = true
}
if (message is Event.RadioStarted) {
recycler.forEach {
it.isEnabled = true
it.isClickable = true
}
}
}
}

View File

@ -250,16 +250,16 @@ class TracksFragment : FFAFragment<Track, TracksAdapter>() {
private fun watchEventBus() {
lifecycleScope.launch(IO) {
EventBus.get().collect { message ->
when (message) {
is Event.DownloadChanged -> refreshDownloadedTrack(message.download)
if (message is Event.DownloadChanged) {
refreshDownloadedTrack(message.download)
}
}
}
lifecycleScope.launch(Main) {
CommandBus.get().collect { command ->
when (command) {
is Command.RefreshTrack -> refreshCurrentTrack(command.track)
if (command is Command.RefreshTrack) {
refreshCurrentTrack(command.track)
}
}
}

View File

@ -7,7 +7,13 @@ import androidx.core.net.toUri
import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.model.DownloadInfo
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.*
import audio.funkwhale.ffa.utils.AppContext
import audio.funkwhale.ffa.utils.Event
import audio.funkwhale.ffa.utils.EventBus
import audio.funkwhale.ffa.utils.Request
import audio.funkwhale.ffa.utils.RequestBus
import audio.funkwhale.ffa.utils.Response
import audio.funkwhale.ffa.utils.mustNormalizeUrl
import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadManager
import com.google.android.exoplayer2.offline.DownloadRequest
@ -20,7 +26,7 @@ import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.koin.java.KoinJavaComponent
import java.util.*
import java.util.Collections
class PinService : DownloadService(AppContext.NOTIFICATION_DOWNLOADS) {
@ -57,8 +63,8 @@ class PinService : DownloadService(AppContext.NOTIFICATION_DOWNLOADS) {
scope.launch(Main) {
RequestBus.get().collect { request ->
when (request) {
is Request.GetDownloads -> request.channel?.trySend(Response.Downloads(getDownloads()))?.isSuccess
if (request is Request.GetDownloads) {
request.channel?.trySend(Response.Downloads(getDownloads()))?.isSuccess
}
}
}

View File

@ -171,61 +171,59 @@ class PlayerService : Service() {
private fun watchEventBus() {
scope.launch(Main) {
CommandBus.get().collect { command ->
when (command) {
is Command.RefreshService -> {
if (queue.metadata.isNotEmpty()) {
CommandBus.send(Command.RefreshTrack(queue.current()))
EventBus.send(Event.StateChanged(player.playWhenReady))
}
}
is Command.ReplaceQueue -> {
if (!command.fromRadio) radioPlayer.stop()
queue.replace(command.queue)
player.prepare(queue.dataSources, true, true)
setPlaybackState(true)
if (command is Command.RefreshService) {
if (queue.metadata.isNotEmpty()) {
CommandBus.send(Command.RefreshTrack(queue.current()))
EventBus.send(Event.StateChanged(player.playWhenReady))
}
} else if (command is Command.ReplaceQueue) {
if (!command.fromRadio) radioPlayer.stop()
is Command.AddToQueue -> queue.append(command.tracks)
is Command.PlayNext -> queue.insertNext(command.track)
is Command.RemoveFromQueue -> queue.remove(command.track)
is Command.MoveFromQueue -> queue.move(command.oldPosition, command.newPosition)
queue.replace(command.queue)
player.prepare(queue.dataSources, true, true)
is Command.PlayTrack -> {
queue.current = command.index
player.seekTo(command.index, C.TIME_UNSET)
setPlaybackState(true)
setPlaybackState(true)
CommandBus.send(Command.RefreshTrack(queue.current()))
} else if (command is Command.AddToQueue) {
queue.append(command.tracks)
} else if (command is Command.PlayNext) {
queue.insertNext(command.track)
} else if (command is Command.RemoveFromQueue) {
queue.remove(command.track)
} else if (command is Command.MoveFromQueue) {
queue.move(command.oldPosition, command.newPosition)
} else if (command is Command.PlayTrack) {
queue.current = command.index
player.seekTo(command.index, C.TIME_UNSET)
CommandBus.send(Command.RefreshTrack(queue.current()))
}
setPlaybackState(true)
is Command.ToggleState -> togglePlayback()
is Command.SetState -> setPlaybackState(command.state)
is Command.NextTrack -> skipToNextTrack()
is Command.PreviousTrack -> skipToPreviousTrack()
is Command.Seek -> seek(command.progress)
is Command.ClearQueue -> {
queue.clear()
player.stop()
}
is Command.ShuffleQueue -> queue.shuffle()
is Command.PlayRadio -> {
queue.clear()
radioPlayer.play(command.radio)
}
is Command.SetRepeatMode -> player.repeatMode = command.mode
is Command.PinTrack -> PinService.download(this@PlayerService, command.track)
is Command.PinTracks -> command.tracks.forEach {
CommandBus.send(Command.RefreshTrack(queue.current()))
} else if (command is Command.ToggleState) {
togglePlayback()
} else if (command is Command.SetState) {
setPlaybackState(command.state)
} else if (command is Command.NextTrack) {
skipToNextTrack()
} else if (command is Command.PreviousTrack) {
skipToPreviousTrack()
} else if (command is Command.Seek) {
seek(command.progress)
} else if (command is Command.ClearQueue) {
queue.clear()
player.stop()
} else if (command is Command.ShuffleQueue) {
queue.shuffle()
} else if (command is Command.PlayRadio) {
queue.clear()
radioPlayer.play(command.radio)
} else if (command is Command.SetRepeatMode) {
player.repeatMode = command.mode
} else if (command is Command.PinTrack) {
PinService.download(this@PlayerService, command.track)
} else if (command is Command.PinTracks) {
command.tracks.forEach {
PinService.download(
this@PlayerService,
it
@ -237,10 +235,12 @@ class PlayerService : Service() {
scope.launch(Main) {
RequestBus.get().collect { request ->
when (request) {
is Request.GetCurrentTrack -> request.channel?.trySend(Response.CurrentTrack(queue.current()))?.isSuccess
is Request.GetState -> request.channel?.trySend(Response.State(player.playWhenReady))?.isSuccess
is Request.GetQueue -> request.channel?.trySend(Response.Queue(queue.get()))?.isSuccess
if (request is Request.GetCurrentTrack) {
request.channel?.trySend(Response.CurrentTrack(queue.current()))?.isSuccess
} else if (request is Request.GetState) {
request.channel?.trySend(Response.State(player.playWhenReady))?.isSuccess
} else if (request is Request.GetQueue) {
request.channel?.trySend(Response.Queue(queue.get()))?.isSuccess
}
}
}

View File

@ -1,8 +1,16 @@
package audio.funkwhale.ffa.repositories
import android.content.Context
import audio.funkwhale.ffa.model.*
import audio.funkwhale.ffa.utils.*
import audio.funkwhale.ffa.model.FFAResponse
import audio.funkwhale.ffa.model.Playlist
import audio.funkwhale.ffa.model.PlaylistsCache
import audio.funkwhale.ffa.model.PlaylistsResponse
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.OAuth
import audio.funkwhale.ffa.utils.Settings
import audio.funkwhale.ffa.utils.authorize
import audio.funkwhale.ffa.utils.gsonDeserializerOf
import audio.funkwhale.ffa.utils.mustNormalizeUrl
import com.github.kittinunf.fuel.Fuel
import com.github.kittinunf.fuel.coroutines.awaitByteArrayResponseResult
import com.github.kittinunf.fuel.coroutines.awaitObjectResponseResult

View File

@ -8,11 +8,9 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import java.io.BufferedReader
import kotlin.math.ceil
interface Upstream<D> {

View File

@ -1,7 +1,15 @@
package audio.funkwhale.ffa.repositories
import android.content.Context
import audio.funkwhale.ffa.model.*
import audio.funkwhale.ffa.model.Album
import audio.funkwhale.ffa.model.AlbumsCache
import audio.funkwhale.ffa.model.AlbumsResponse
import audio.funkwhale.ffa.model.Artist
import audio.funkwhale.ffa.model.ArtistsCache
import audio.funkwhale.ffa.model.ArtistsResponse
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.model.TracksCache
import audio.funkwhale.ffa.model.TracksResponse
import audio.funkwhale.ffa.utils.OAuth
import audio.funkwhale.ffa.utils.gsonDeserializerOf
import audio.funkwhale.ffa.utils.mustNormalizeUrl

View File

@ -25,7 +25,7 @@ import kotlinx.coroutines.runBlocking
import net.openid.appauth.ClientSecretPost
import java.io.Reader
import java.text.SimpleDateFormat
import java.util.*
import java.util.Date
import kotlin.coroutines.CoroutineContext
inline fun <D> Flow<Repository.Response<D>>.untilNetwork(
@ -82,7 +82,7 @@ fun Request.authorize(context: Context, oAuth: OAuth): Request {
state.performActionWithFreshTokens(tokenService, auth) { token, _, e ->
if (e != null) {
Log.e("Request.authorize()", "performActionWithFreshToken failed: ${e}")
Log.e("Request.authorize()", "performActionWithFreshToken failed: $e")
Log.e("Request.authorize()", Log.getStackTraceString(e))
}
if (token == old) {

View File

@ -15,7 +15,7 @@ object FFACache {
return digest.fold("") { acc, it -> acc + "%02x".format(it) }
}
fun set(context: Context?, key:String, value: String){
fun set(context: Context?, key: String, value: String) {
set(context, key, value.toByteArray())
}

View File

@ -71,9 +71,8 @@ class OAuth(private val authorizationServiceFactory: AuthorizationServiceFactory
} else {
false
}
).also {
it.logInfo("isAuthorized()")
}
)
.also { it.logInfo("isAuthorized()") }
}
private fun AuthState.validAuthorization() = this.isAuthorized && !this.needsTokenRefresh
@ -102,7 +101,7 @@ class OAuth(private val authorizationServiceFactory: AuthorizationServiceFactory
runBlocking {
refreshService.performTokenRequest(refreshRequest, auth) { response, e ->
if (e != null) {
Log.e("OAuth", "performTokenRequest failed: ${e}")
Log.e("OAuth", "performTokenRequest failed: $e")
Log.e("OAuth", Log.getStackTraceString(e))
} else {
state.apply {
@ -213,13 +212,13 @@ class OAuth(private val authorizationServiceFactory: AuthorizationServiceFactory
requestService.performTokenRequest(it.createTokenExchangeRequest(), auth) { response, e ->
if (e != null) {
Log.e("FFA", "performTokenRequest failed: ${e}")
Log.e("FFA", "performTokenRequest failed: $e")
Log.e("FFA", Log.getStackTraceString(e))
} else {
state.apply {
update(response, e)
save()
}
update(response, e)
save()
}
}
if (response != null) success()

View File

@ -8,7 +8,7 @@ buildscript {
dependencies {
classpath("com.android.tools.build:gradle:7.2.2")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
classpath("com.github.bjoernq:unmockplugin:0.7.9")
classpath("com.github.ben-manes:gradle-versions-plugin:0.42.0")
classpath("org.jacoco:org.jacoco.core:0.8.7")