From 4c4e67300246a04297d2d297bbf1c5e8de48f245 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Mon, 30 May 2022 18:39:13 +0300 Subject: [PATCH 01/15] proguard for coroutines and kapt for glide --- androidApp/build.gradle.kts | 2 +- androidApp/proguard-rules.pro | 24 ++++++++++++++++++++++++ shared/build.gradle.kts | 13 ++++++------- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 682e04b..4e9fd18 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -33,7 +33,7 @@ dependencies { implementation("com.google.dagger:hilt-android:2.38.1") kapt("com.google.dagger:hilt-android-compiler:2.38.1") implementation("com.github.bumptech.glide:glide:4.13.2") - annotationProcessor("com.github.bumptech.glide:compiler:4.13.2") + kapt("com.github.bumptech.glide:compiler:4.13.2") implementation("com.google.accompanist:accompanist-swiperefresh:0.24.1-alpha") implementation("androidx.core:core-splashscreen:1.0.0-rc01") diff --git a/androidApp/proguard-rules.pro b/androidApp/proguard-rules.pro index 3fd415d..4192fc2 100644 --- a/androidApp/proguard-rules.pro +++ b/androidApp/proguard-rules.pro @@ -59,3 +59,27 @@ -keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder { *** rewind(); } + + +# Allow R8 to optimize away the FastServiceLoader. +# Together with ServiceLoader optimization in R8 +# this results in direct instantiation when loading Dispatchers.Main +-assumenosideeffects class kotlinx.coroutines.internal.MainDispatcherLoader { + boolean FAST_SERVICE_LOADER_ENABLED return false; +} + +-assumenosideeffects class kotlinx.coroutines.internal.FastServiceLoaderKt { + boolean ANDROID_DETECTED return true; +} + +# Disable support for "Missing Main Dispatcher", since we always have Android main dispatcher +-assumenosideeffects class kotlinx.coroutines.internal.MainDispatchersKt { + boolean SUPPORT_MISSING return false; +} + +# Statically turn off all debugging facilities and assertions +-assumenosideeffects class kotlinx.coroutines.DebugKt { + boolean getASSERTIONS_ENABLED() return false; + boolean getDEBUG() return false; + boolean getRECOVER_STACK_TRACES() return false; +} \ No newline at end of file diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index e35abf9..df22627 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -3,7 +3,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget plugins { kotlin("multiplatform") id("com.android.library") - kotlin("plugin.serialization") version "1.6.20" + kotlin("plugin.serialization") version "1.6.21" id("com.squareup.sqldelight") } @@ -24,16 +24,15 @@ kotlin { } } sourceSets { - val ktor_version = "1.6.3" + val ktor_version = "2.0.2" val commonMain by getting { dependencies { - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.3.2") implementation("io.ktor:ktor-client-core:$ktor_version") - implementation("io.ktor:ktor-client-json:$ktor_version") + implementation("io.ktor:ktor-client-content-negotiation:$ktor_version") + implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version") implementation("io.ktor:ktor-client-logging:$ktor_version") - implementation("io.ktor:ktor-client-serialization:$ktor_version") - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.3.2") } } val commonTest by getting { From 6c93a05efc3138718f0f430a45d414f05e53ae96 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Mon, 30 May 2022 18:40:37 +0300 Subject: [PATCH 02/15] client update --- .../justlisten/datalayer/utils/Constants.kt | 2 +- .../datalayer/webservices/ApiClient.kt | 36 +++++++++------ .../screens/playlist/PlaylistInit.kt | 44 ++++++++++++------- 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/utils/Constants.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/utils/Constants.kt index b061f90..a4f3cb3 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/utils/Constants.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/utils/Constants.kt @@ -74,7 +74,7 @@ object Constants { ) val usedBasedUrl = mutableMapOf() - val bestResponseTime = mutableMapOf() + val bestResponseTime = mutableMapOf() val list = listOf("Electronic", "Rock", "Trending", "Pop", "Classical") diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/ApiClient.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/ApiClient.kt index 590da9e..f589f64 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/ApiClient.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/ApiClient.kt @@ -5,10 +5,11 @@ import com.rld.justlisten.datalayer.utils.Constants.listOfBaseUrls import com.rld.justlisten.datalayer.utils.Constants.usedBasedUrl import com.rld.justlisten.datalayer.webservices.apis.playlistcalls.PlayListResponse import io.ktor.client.* -import io.ktor.client.features.* -import io.ktor.client.features.json.JsonFeature -import io.ktor.client.features.json.serializer.* +import io.ktor.client.call.* +import io.ktor.client.plugins.* +import io.ktor.client.plugins.contentnegotiation.* import io.ktor.client.request.* +import io.ktor.serialization.kotlinx.json.* import kotlinx.datetime.Clock import kotlinx.serialization.json.Json import kotlin.collections.set @@ -17,12 +18,21 @@ import kotlin.random.Random class ApiClient { val client = HttpClient { - install(JsonFeature) { - serializer = KotlinxSerializer(Json { + engine { + // this: HttpClientEngineConfig + threadsCount = 4 + } + + install(ContentNegotiation) { + json(Json { + isLenient = true ignoreUnknownKeys = true + useAlternativeNames = false }) } install(HttpTimeout) { + requestTimeoutMillis = 1000 + socketTimeoutMillis = 2000 requestTimeoutMillis = 4000 } } @@ -37,21 +47,21 @@ class ApiClient { val baseUrl = usedBasedUrl["goodBaseUrl"] ?: listOfBaseUrls[random] val url = "${baseUrl}/v1$endpoint" try { - val firstTime = Clock.System.now().nanosecondsOfSecond - val response = client.get(url) - when (response) { - is PlayListResponse -> wasSuccessful = response.error.isNullOrEmpty() + val response = client.get(url) + val body = response.body() + when (body) { + is PlayListResponse -> wasSuccessful = body.error.isNullOrEmpty() } if (wasSuccessful) { - val secondTime = Clock.System.now().nanosecondsOfSecond - val responseTime = secondTime - firstTime - val savedBestResponseTime = bestResponseTime["goodBaseUrl"] ?: Int.MAX_VALUE + val responseTime = + response.responseTime.timestamp - response.requestTime.timestamp + val savedBestResponseTime = bestResponseTime["goodBaseUrl"] ?: Long.MAX_VALUE bestResponseTime["goodBaseUrl"] = if (savedBestResponseTime > responseTime) responseTime else savedBestResponseTime usedBasedUrl["goodBaseUrl"] = if (bestResponseTime["goodBaseUrl"] == responseTime) baseUrl else usedBasedUrl["goodBaseUrl"] ?: baseUrl - return response + return body } } catch (e: Exception) { numberOfCalls += 1 diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistInit.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistInit.kt index 251b1c6..9277c00 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistInit.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/playlist/PlaylistInit.kt @@ -9,7 +9,7 @@ import com.rld.justlisten.viewmodel.screens.ScreenInitSettings import com.rld.justlisten.viewmodel.screens.search.TrackItem import kotlinx.coroutines.Deferred import kotlinx.coroutines.async -import kotlinx.coroutines.supervisorScope +import kotlinx.coroutines.coroutineScope import kotlinx.serialization.Serializable import kotlin.random.Random @@ -27,26 +27,38 @@ fun Navigation.initPlaylist(params: PlaylistParams) = ScreenInitSettings( var queryIndex = Random.nextInt(0, list.size) val queryIndex2 = Random.nextInt(0, list.size) if (queryIndex == queryIndex2) { - if (queryIndex>0) + if (queryIndex > 0) queryIndex -= 1 else queryIndex += 1 } - supervisorScope { + coroutineScope { playlist = async { dataRepository.getPlaylist(index = 20, PlayListEnum.TOP_PLAYLIST) } tracks = async { dataRepository.getTracks(limit = 16, "Electronic", "week") } - remix = async { dataRepository.getPlaylist(index = 20, PlayListEnum.REMIX, queryPlaylist = list[queryIndex]) } - hot = async { dataRepository.getPlaylist(index = 20, PlayListEnum.HOT, queryPlaylist = list[queryIndex2]) } - } - stateManager.updateScreen(PlaylistState::class) { - it.copy( - remixPlaylist = remix.await(), - isLoading = false, - playlistItems = playlist.await(), - hotPlaylist = hot.await(), - queryIndex = queryIndex, - queryIndex2 = queryIndex2, - tracksList = tracks.await() - ) + remix = async { + dataRepository.getPlaylist( + index = 20, + PlayListEnum.REMIX, + queryPlaylist = list[queryIndex] + ) + } + hot = async { + dataRepository.getPlaylist( + index = 20, + PlayListEnum.HOT, + queryPlaylist = list[queryIndex2] + ) + } + stateManager.updateScreen(PlaylistState::class) { + it.copy( + remixPlaylist = remix.await(), + isLoading = false, + playlistItems = playlist.await(), + hotPlaylist = hot.await(), + queryIndex = queryIndex, + queryIndex2 = queryIndex2, + tracksList = tracks.await() + ) + } } }, reinitOnEachNavigation = false From e332b9deaea510740299399ae78edf27751e7578 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 08:58:29 +0300 Subject: [PATCH 03/15] update to latest compose --- androidApp/build.gradle.kts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 4e9fd18..31f44f3 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -16,12 +16,12 @@ dependencies { implementation("androidx.activity:activity-compose:1.4.0") implementation("androidx.palette:palette-ktx:1.0.0") - implementation("androidx.compose.ui:ui-util:1.2.0-beta02") + implementation("androidx.compose.ui:ui-util:1.2.0-beta03") + implementation("androidx.compose.material:material:1.2.0-beta03") + implementation("androidx.compose.ui:ui:1.2.0-beta03") implementation("androidx.compose.animation:animation:1.1.1") - implementation("androidx.compose.ui:ui:1.2.0-beta02") debugImplementation("androidx.compose.ui:ui-tooling:1.1.1") implementation("androidx.compose.ui:ui-tooling-preview:1.1.1") - implementation("androidx.compose.material:material:1.2.0-beta02") implementation("com.google.android.exoplayer:exoplayer:2.17.1") implementation("com.google.android.exoplayer:extension-mediasession:2.17.1") @@ -50,11 +50,11 @@ kapt { } android { - compileSdk = 31 + compileSdk = 32 defaultConfig { applicationId = "com.rld.justlisten.android" minSdk = 21 - targetSdk = 31 + targetSdk = 32 versionCode = 14 versionName = "1.0.2" vectorDrawables { From eb559b0ea05be9985154641ebaa192ff0ad66506 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 09:05:22 +0300 Subject: [PATCH 04/15] remove unused --- .../com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt index afb3073..433b08b 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt @@ -107,7 +107,7 @@ fun Navigation.ScreenPicker( }, onSearchClicked = { navigate(Search) }, refreshScreen = { events.refreshScreen() }, - onSongPressed = { songId, title, user, songIcon -> + onSongPressed = { songId, _, _, _ -> if (isPlayerReady.value) { isPlayerReady.value = false } From dcf1bc6010e333cac4db470096cbb00eabd8be6b Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 12:50:19 +0300 Subject: [PATCH 05/15] private constructor --- .../rld/justlisten/android/exoplayer/MusicServiceConnection.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicServiceConnection.kt b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicServiceConnection.kt index c7f5829..3e43fbd 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicServiceConnection.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicServiceConnection.kt @@ -17,7 +17,7 @@ import kotlinx.coroutines.* import javax.inject.Inject class MusicServiceConnection @Inject constructor( - val musicSource: MusicSource, + private val musicSource: MusicSource, context: Context ) { From d8112d0a124b9feee4d0e27a8b75f2437e682e16 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 14:04:48 +0300 Subject: [PATCH 06/15] fix slider --- .../android/exoplayer/MusicServiceConnection.kt | 3 ++- .../playbar/components/PlayBarActionsMaximized.kt | 15 ++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicServiceConnection.kt b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicServiceConnection.kt index 3e43fbd..2758f1c 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicServiceConnection.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicServiceConnection.kt @@ -75,13 +75,14 @@ class MusicServiceConnection @Inject constructor( serviceScope.launch { while (!sliderClicked.value) { ensureActive() + delay(100L) val pos = playbackState.value?.currentPlaybackPosition if (songDuration.value != pos) { pos?.let { songDuration.value = it } } - delay(1000L) + delay(900L) } } } diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayBarActionsMaximized.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayBarActionsMaximized.kt index 03b8c6b..527c3e3 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayBarActionsMaximized.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/bottombars/playbar/components/PlayBarActionsMaximized.kt @@ -1,13 +1,10 @@ package com.rld.justlisten.android.ui.bottombars.playbar.components import android.media.session.PlaybackState -import android.support.v4.media.session.PlaybackStateCompat import android.support.v4.media.session.PlaybackStateCompat.* import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.DragInteraction -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.remember import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.PressInteraction import androidx.compose.foundation.layout.* @@ -16,7 +13,6 @@ import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp @@ -26,10 +22,8 @@ import com.rld.justlisten.android.exoplayer.MusicService import com.rld.justlisten.android.exoplayer.MusicServiceConnection import com.rld.justlisten.android.ui.extensions.ModifiedSlider import com.rld.justlisten.android.ui.utils.offsetX -import com.rld.justlisten.android.ui.utils.offsetY import com.rld.justlisten.android.ui.utils.widthSize import kotlinx.coroutines.InternalCoroutinesApi -import kotlinx.coroutines.flow.collect @InternalCoroutinesApi @Composable @@ -48,13 +42,17 @@ fun PlayBarActionsMaximized( interactionSource.interactions.collect { interaction -> when (interaction) { is PressInteraction.Press -> { + musicServiceConnection.sliderClicked.value = true + } + is PressInteraction.Release -> { musicServiceConnection.transportControls.seekTo(musicServiceConnection.songDuration.value) musicServiceConnection.sliderClicked.value = false musicServiceConnection.updateSong() } - is PressInteraction.Release -> {} is PressInteraction.Cancel -> {} - is DragInteraction.Start -> {} + is DragInteraction.Start -> { + musicServiceConnection.sliderClicked.value = true + } is DragInteraction.Stop -> { musicServiceConnection.transportControls.seekTo(musicServiceConnection.songDuration.value) musicServiceConnection.sliderClicked.value = false @@ -87,7 +85,6 @@ fun PlayBarActionsMaximized( .offset(x = offsetX(currentFraction, maxWidth).dp) .width(widthSize(currentFraction, maxWidth).dp), value = sliderPosition, onValueChange = { - musicServiceConnection.sliderClicked.value = true musicServiceConnection.songDuration.value = (it * MusicService.curSongDuration).toLong() }) From d4684a6b5f095a2d62cf9b18d597b6a439263187 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 15:33:48 +0300 Subject: [PATCH 07/15] Display error when the song is not working from audius side --- .../android/exoplayer/callbacks/MusicPlayerEventListener.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/callbacks/MusicPlayerEventListener.kt b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/callbacks/MusicPlayerEventListener.kt index f8f6661..9e5dab6 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/callbacks/MusicPlayerEventListener.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/callbacks/MusicPlayerEventListener.kt @@ -1,11 +1,11 @@ package com.rld.justlisten.android.exoplayer.callbacks import android.widget.Toast -import com.rld.justlisten.android.exoplayer.MusicNotificationManager -import com.rld.justlisten.android.exoplayer.MusicService import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.PlaybackException import com.google.android.exoplayer2.Player +import com.rld.justlisten.android.exoplayer.MusicNotificationManager +import com.rld.justlisten.android.exoplayer.MusicService class MusicPlayerEventListener( private val musicService: MusicService, @@ -22,7 +22,7 @@ class MusicPlayerEventListener( override fun onPlayerError(error: PlaybackException) { super.onPlayerError(error) - Toast.makeText(musicService, "Error", Toast.LENGTH_SHORT).show() + Toast.makeText(musicService, "Unfortunately this song has issues, try another one", Toast.LENGTH_SHORT).show() } override fun onPlaybackStateChanged(playbackState: Int) { From fd8158e54483281631ec7a83b37c597d85b02a48 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 15:36:34 +0300 Subject: [PATCH 08/15] version 1.0.3 --- androidApp/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 31f44f3..09f94c5 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -55,8 +55,8 @@ android { applicationId = "com.rld.justlisten.android" minSdk = 21 targetSdk = 32 - versionCode = 14 - versionName = "1.0.2" + versionCode = 15 + versionName = "1.0.3" vectorDrawables { useSupportLibrary = true } From 4e9262256f702f3fd4bd82c77e8dec596ab3d9da Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 22:22:03 +0300 Subject: [PATCH 09/15] fix issue of the app crashing on low bandwidth network --- .../exoplayer/MusicNotificationManager.kt | 37 +++++++++++-------- .../android/exoplayer/MusicService.kt | 15 +++++--- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicNotificationManager.kt b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicNotificationManager.kt index acb7937..c7664f7 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicNotificationManager.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicNotificationManager.kt @@ -3,12 +3,14 @@ package com.rld.justlisten.android.exoplayer import android.app.PendingIntent import android.content.Context import android.graphics.Bitmap +import android.graphics.drawable.BitmapDrawable import android.net.Uri import android.support.v4.media.session.MediaControllerCompat import android.support.v4.media.session.MediaSessionCompat -import com.bumptech.glide.Glide -import com.bumptech.glide.load.engine.DiskCacheStrategy -import com.bumptech.glide.request.RequestOptions +import coil.ImageLoader +import coil.request.CachePolicy +import coil.request.ImageRequest +import coil.request.SuccessResult import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.ui.PlayerNotificationManager import com.rld.justlisten.android.R @@ -98,19 +100,24 @@ class MusicNotificationManager( private suspend fun resolveUriAsBitmap(uri: Uri): Bitmap? { return withContext(Dispatchers.IO) { - // Block on downloading artwork. - Glide.with(context).applyDefaultRequestOptions(glideOptions) - .asBitmap() - .load(uri) - .submit(NOTIFICATION_LARGE_ICON_SIZE, NOTIFICATION_LARGE_ICON_SIZE) - .get() + getBitmap(uri) } } } -} - -const val NOTIFICATION_LARGE_ICON_SIZE = 144 // px -private val glideOptions = RequestOptions() - .fallback(R.drawable.ic_add_to_playlist_background) - .diskCacheStrategy(DiskCacheStrategy.DATA) + private suspend fun getBitmap(uri: Uri): Bitmap? { + val loader = ImageLoader(context) + val request = ImageRequest.Builder(context) + .data(uri) + .memoryCachePolicy(CachePolicy.ENABLED) + .diskCachePolicy(CachePolicy.ENABLED) + .allowHardware(false) // Disable hardware bitmaps. + .build() + return try { + val result = (loader.execute(request) as SuccessResult).drawable + (result as BitmapDrawable).bitmap + } catch (e: Exception) { + null + } + } +} diff --git a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicService.kt b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicService.kt index 183eb74..50ac73b 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicService.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/exoplayer/MusicService.kt @@ -8,18 +8,21 @@ import android.support.v4.media.MediaDescriptionCompat import android.support.v4.media.MediaMetadataCompat import android.support.v4.media.session.MediaSessionCompat import androidx.media.MediaBrowserServiceCompat +import com.google.android.exoplayer2.ExoPlayer +import com.google.android.exoplayer2.Player +import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector +import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator import com.rld.justlisten.android.exoplayer.callbacks.MusicPlaybackPreparer import com.rld.justlisten.android.exoplayer.callbacks.MusicPlayerEventListener import com.rld.justlisten.android.exoplayer.callbacks.MusicPlayerNotificationListener import com.rld.justlisten.android.exoplayer.library.extension.toMediaItem import com.rld.justlisten.android.exoplayer.utils.Constants.MEDIA_ROOT_ID import com.rld.justlisten.android.exoplayer.utils.Constants.NETWORK_ERROR -import com.google.android.exoplayer2.ExoPlayer -import com.google.android.exoplayer2.Player -import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector -import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel import javax.inject.Inject private const val SERVICE_TAG = "MusicService" @@ -32,7 +35,7 @@ class MusicService : MediaBrowserServiceCompat() { lateinit var musicNotificationManager: MusicNotificationManager - private val serviceJob = Job() + private val serviceJob = SupervisorJob() private val serviceScope = CoroutineScope(Dispatchers.Main + serviceJob) private lateinit var mediaSession: MediaSessionCompat From cf3ec532fef5200f09279558af632d5468a6a95a Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 22:33:22 +0300 Subject: [PATCH 10/15] rollback due to bottomsheet getting showed on top for 1 second before loading --- androidApp/build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 09f94c5..89b64ff 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -16,9 +16,9 @@ dependencies { implementation("androidx.activity:activity-compose:1.4.0") implementation("androidx.palette:palette-ktx:1.0.0") - implementation("androidx.compose.ui:ui-util:1.2.0-beta03") - implementation("androidx.compose.material:material:1.2.0-beta03") - implementation("androidx.compose.ui:ui:1.2.0-beta03") + implementation("androidx.compose.ui:ui-util:1.2.0-beta02") + implementation("androidx.compose.material:material:1.2.0-beta02") + implementation("androidx.compose.ui:ui:1.2.0-beta02") implementation("androidx.compose.animation:animation:1.1.1") debugImplementation("androidx.compose.ui:ui-tooling:1.1.1") implementation("androidx.compose.ui:ui-tooling-preview:1.1.1") From 6c3d14237c13fb5a3a6546d8aee5a679a76ac160 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 22:33:34 +0300 Subject: [PATCH 11/15] timeout --- .../com/rld/justlisten/datalayer/webservices/ApiClient.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/ApiClient.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/ApiClient.kt index f589f64..6e496f9 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/ApiClient.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/datalayer/webservices/ApiClient.kt @@ -31,9 +31,9 @@ class ApiClient { }) } install(HttpTimeout) { - requestTimeoutMillis = 1000 - socketTimeoutMillis = 2000 - requestTimeoutMillis = 4000 + connectTimeoutMillis = 3000 + socketTimeoutMillis = 4500 + requestTimeoutMillis = 10000 } } From ee9ce2c14d6f1f82c8c1e20c63e80970b74d6d97 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 23:08:14 +0300 Subject: [PATCH 12/15] remove glide --- androidApp/build.gradle.kts | 4 ---- androidApp/proguard-rules.pro | 16 ---------------- 2 files changed, 20 deletions(-) diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 89b64ff..2d5b615 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -32,14 +32,10 @@ dependencies { implementation("io.coil-kt:coil-compose:2.1.0") implementation("com.google.dagger:hilt-android:2.38.1") kapt("com.google.dagger:hilt-android-compiler:2.38.1") - implementation("com.github.bumptech.glide:glide:4.13.2") - kapt("com.github.bumptech.glide:compiler:4.13.2") implementation("com.google.accompanist:accompanist-swiperefresh:0.24.1-alpha") implementation("androidx.core:core-splashscreen:1.0.0-rc01") - - androidTestImplementation("androidx.compose.ui:ui-test-junit4:${rootProject.extra["compose_version"]}") debugImplementation("androidx.compose.ui:ui-tooling:${rootProject.extra["compose_version"]}") debugImplementation("com.squareup.leakcanary:leakcanary-android:2.7") diff --git a/androidApp/proguard-rules.pro b/androidApp/proguard-rules.pro index 4192fc2..d35a709 100644 --- a/androidApp/proguard-rules.pro +++ b/androidApp/proguard-rules.pro @@ -45,22 +45,6 @@ kotlinx.serialization.KSerializer serializer(...); } -# @Serializable and @Polymorphic are used at runtime for polymorphic serialization. --keepattributes RuntimeVisibleAnnotations,AnnotationDefault - --keep public class * implements com.bumptech.glide.module.GlideModule --keep class * extends com.bumptech.glide.module.AppGlideModule { - (...); -} --keep public enum com.bumptech.glide.load.ImageHeaderParser$** { - **[] $VALUES; - public *; -} --keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder { - *** rewind(); -} - - # Allow R8 to optimize away the FastServiceLoader. # Together with ServiceLoader optimization in R8 # this results in direct instantiation when loading Dispatchers.Main From 67638594473847d27cc01fd1ee0960f270cb454e Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 23:17:27 +0300 Subject: [PATCH 13/15] remove unused parameters --- .../rld/justlisten/android/ui/screenpicker/ScreenPicker.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt index 433b08b..6d7652d 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/screenpicker/ScreenPicker.kt @@ -1,6 +1,7 @@ package com.rld.justlisten.android.ui.screenpicker import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.ExperimentalComposeUiApi import com.rld.justlisten.Navigation import com.rld.justlisten.ScreenIdentifier @@ -44,7 +45,7 @@ fun Navigation.ScreenPicker( musicServiceConnection: MusicServiceConnection, settingsUpdated: () -> Unit ) { - val isPlayerReady: MutableState = remember { + val isPlayerReady: MutableState = rememberSaveable{ mutableStateOf(false) } @@ -158,7 +159,7 @@ fun Navigation.ScreenPicker( isPlayerReady.value = false }, searchScreenState = stateProvider.get(screenIdentifier = screenIdentifier), - onSongPressed = { songId, title, user, songIcon -> + onSongPressed = { songId, _, _, _ -> playMusicFromId( musicServiceConnection, (stateProvider.get(screenIdentifier = screenIdentifier) as SearchScreenState).searchResultTracks, From 033679f52e60d013f58e18af6704b6f1fb486b09 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sat, 4 Jun 2022 23:29:57 +0300 Subject: [PATCH 14/15] Fixed wrong naming in playlists details screen --- .../components/BoxTopSection.kt | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BoxTopSection.kt b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BoxTopSection.kt index 130847f..f9113c7 100644 --- a/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BoxTopSection.kt +++ b/androidApp/src/main/java/com/rld/justlisten/android/ui/playlistdetailscreen/components/BoxTopSection.kt @@ -1,8 +1,13 @@ package com.rld.justlisten.android.ui.playlistdetailscreen.components import androidx.compose.animation.core.animateDpAsState -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.Image +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme.typography @@ -13,6 +18,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -35,8 +41,10 @@ fun BoxTopSection(scrollState: MutableState, playlistDetailState: Playlis .padding(8.dp) ) Text( - text = playlistDetailState.playlistName, - style = typography.h5.copy(fontWeight = FontWeight.ExtraBold), + text = playlistDetailState.playListCreatedBy, + style = typography.subtitle2.copy(fontWeight = FontWeight.ExtraBold), + maxLines = 1, + textAlign = TextAlign.Center, modifier = Modifier.padding(8.dp), ) Text( @@ -51,7 +59,9 @@ fun BoxTopSection(scrollState: MutableState, playlistDetailState: Playlis .padding(vertical = 4.dp, horizontal = 24.dp) ) Text( - text = "Playlist created by ${playlistDetailState.playListCreatedBy}", + text = "Created by ${playlistDetailState.playlistName}", + maxLines = 1, + textAlign = TextAlign.Center, style = typography.subtitle2, modifier = Modifier.padding(4.dp) ) From 7a0d24f43558d02ace38b28da26c05e1d880cab1 Mon Sep 17 00:00:00 2001 From: laurentiu Date: Sun, 5 Jun 2022 00:20:10 +0300 Subject: [PATCH 15/15] Fixed not showing searches --- .../viewmodel/screens/search/SearchScreenEvents.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/search/SearchScreenEvents.kt b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/search/SearchScreenEvents.kt index 399b801..84c3724 100644 --- a/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/search/SearchScreenEvents.kt +++ b/shared/src/commonMain/kotlin/com/rld/justlisten/viewmodel/screens/search/SearchScreenEvents.kt @@ -23,13 +23,13 @@ fun Events.searchFor(searchInfo: String) = screenCoroutine { coroutineScope { tracksList = async { dataRepository.searchForTracks(searchInfo) } playList = async { dataRepository.searchForPlaylist(searchInfo) } + val trackListResult = tracksList.await() + val playlistResult = playList.await() + searchState.copy( + searchResultTracks = trackListResult, isLoading = false, searchFor = searchInfo, + searchResultPlaylist = playlistResult + ) } - val trackListResult = tracksList.await() - val playlistResult = playList.await() - searchState.copy( - searchResultTracks = trackListResult, isLoading = false, searchFor = searchInfo, - searchResultPlaylist = playlistResult - ) } }