diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 389ec275..847dc6dc 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -40,7 +40,6 @@
-
(null) }
+ var pic by remember(link) {
+ mutableStateOf(null)
+ }
LaunchedEffect(link) {
withContext(dispatcherIO) {
diff --git a/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt b/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt
index 744c52e2..e56a099e 100644
--- a/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt
+++ b/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt
@@ -21,15 +21,23 @@ package com.shabinder.common.uikit
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.vectorResource
import com.shabinder.common.database.R
import com.shabinder.common.translations.Strings
import kotlinx.coroutines.flow.MutableStateFlow
+@Composable
+internal actual fun imageVectorResource(id: T): ImageVector =
+ ImageVector.Companion.vectorResource(id as Int)
+
@Composable
actual fun DownloadImageTick() {
Image(
- painterResource(R.drawable.ic_tick),
+ getCachedPainter(R.drawable.ic_tick),
Strings.downloadDone()
)
}
@@ -37,7 +45,7 @@ actual fun DownloadImageTick() {
@Composable
actual fun DownloadImageError(modifier: Modifier) {
Image(
- painterResource(R.drawable.ic_error),
+ getCachedPainter(R.drawable.ic_error),
Strings.downloadError(),
modifier = modifier
)
@@ -46,44 +54,44 @@ actual fun DownloadImageError(modifier: Modifier) {
@Composable
actual fun DownloadImageArrow(modifier: Modifier) {
Image(
- painterResource(R.drawable.ic_arrow),
+ getCachedPainter(R.drawable.ic_arrow),
Strings.downloadStart(),
modifier
)
}
@Composable
-actual fun DownloadAllImage() = painterResource(R.drawable.ic_download_arrow)
+actual fun DownloadAllImage() = getCachedPainter(R.drawable.ic_download_arrow)
@Composable
-actual fun ShareImage() = painterResource(R.drawable.ic_share_open)
+actual fun ShareImage() = getCachedPainter(R.drawable.ic_share_open)
@Composable
-actual fun PlaceHolderImage() = painterResource(R.drawable.ic_song_placeholder)
+actual fun PlaceHolderImage() = getCachedPainter(R.drawable.ic_song_placeholder)
@Composable
-actual fun SpotiFlyerLogo() = painterResource(R.drawable.ic_spotiflyer_logo)
+actual fun SpotiFlyerLogo() = getCachedPainter(R.drawable.ic_spotiflyer_logo)
@Composable
actual fun HeartIcon() = painterResource(R.drawable.ic_heart)
@Composable
-actual fun SpotifyLogo() = painterResource(R.drawable.ic_spotify_logo)
+actual fun SpotifyLogo() = getCachedPainter(R.drawable.ic_spotify_logo)
@Composable
-actual fun SaavnLogo() = painterResource(R.drawable.ic_jio_saavn_logo)
+actual fun SaavnLogo() = getCachedPainter(R.drawable.ic_jio_saavn_logo)
@Composable
-actual fun GaanaLogo() = painterResource(R.drawable.ic_gaana)
+actual fun GaanaLogo() = getCachedPainter(R.drawable.ic_gaana)
@Composable
-actual fun YoutubeLogo() = painterResource(R.drawable.ic_youtube)
+actual fun YoutubeLogo() = getCachedPainter(R.drawable.ic_youtube)
@Composable
-actual fun YoutubeMusicLogo() = painterResource(R.drawable.ic_youtube_music_logo)
+actual fun YoutubeMusicLogo() = getCachedPainter(R.drawable.ic_youtube_music_logo)
@Composable
-actual fun GithubLogo() = painterResource(R.drawable.ic_github)
+actual fun GithubLogo() = getCachedPainter(R.drawable.ic_github)
@Composable
actual fun PaypalLogo() = painterResource(R.drawable.ic_paypal_logo)
@@ -100,4 +108,4 @@ actual fun Toast(
duration: ToastDuration
) {
// We Have Android's Implementation of Toast so its just Empty
-}
+}
\ No newline at end of file
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt
index d89974aa..6be14625 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt
@@ -15,11 +15,27 @@
*/
@file:Suppress("FunctionName")
+
package com.shabinder.common.uikit
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.graphics.vector.rememberVectorPainter
+import com.shabinder.common.caching.Cache
+
+private val ImageCache = Cache.Builder.newBuilder()
+ .maximumCacheSize(15).build()
+
+@Composable
+internal expect fun imageVectorResource(id: T): ImageVector
+
+@Composable
+fun getCachedPainter(key: K): Painter {
+ return rememberVectorPainter(
+ ImageCache.get(key) ?: imageVectorResource(key).also { ImageCache.put(key, it) })
+}
@Composable
expect fun DownloadImageTick()
diff --git a/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt b/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt
index ee2f49e3..2c4c1a91 100644
--- a/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt
+++ b/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt
@@ -15,19 +15,26 @@
*/
@file:Suppress("FunctionName")
+
package com.shabinder.common.uikit
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
+import androidx.compose.ui.res.loadXmlImageVector
import androidx.compose.ui.res.vectorXmlResource
+@Composable
+internal actual fun imageVectorResource(id: T): ImageVector =
+ vectorXmlResource(id as String)
+
@Composable
actual fun DownloadImageTick() {
Image(
- vectorXmlResource("drawable/ic_tick.xml"),
+ getCachedPainter("drawable/ic_tick.xml"),
"Downloaded"
)
}
@@ -35,7 +42,7 @@ actual fun DownloadImageTick() {
@Composable
actual fun DownloadImageError(modifier: Modifier) {
Image(
- vectorXmlResource("drawable/ic_error.xml"),
+ getCachedPainter("drawable/ic_error.xml"),
"Can't Download",
modifier = modifier
)
@@ -44,51 +51,61 @@ actual fun DownloadImageError(modifier: Modifier) {
@Composable
actual fun DownloadImageArrow(modifier: Modifier) {
Image(
- vectorXmlResource("drawable/ic_arrow.xml"),
+ getCachedPainter("drawable/ic_arrow.xml"),
"Download",
modifier
)
}
@Composable
-actual fun DownloadAllImage() = rememberVectorPainter(vectorXmlResource("drawable/ic_download_arrow.xml")) as Painter
+actual fun DownloadAllImage() = getCachedPainter("drawable/ic_download_arrow.xml")
+
@Composable
-actual fun ShareImage() = rememberVectorPainter(vectorXmlResource("drawable/ic_share_open.xml")) as Painter
+actual fun ShareImage() = getCachedPainter("drawable/ic_share_open.xml")
@Composable
-actual fun PlaceHolderImage() = rememberVectorPainter(vectorXmlResource("drawable/music.xml"))
- as Painter
-@Composable
-actual fun SpotiFlyerLogo() =
- rememberVectorPainter(vectorXmlResource("drawable/ic_spotiflyer_logo.xml")) as Painter
+actual fun PlaceHolderImage() = getCachedPainter("drawable/music.xml")
@Composable
-actual fun HeartIcon() = rememberVectorPainter(vectorXmlResource("drawable/ic_heart.xml")) as Painter
+actual fun SpotiFlyerLogo() = getCachedPainter("drawable/ic_spotiflyer_logo.xml")
@Composable
-actual fun SpotifyLogo() = rememberVectorPainter(vectorXmlResource("drawable/ic_spotify_logo.xml")) as Painter
+actual fun HeartIcon() =
+ getCachedPainter("drawable/ic_heart.xml")
@Composable
-actual fun SaavnLogo() = rememberVectorPainter(vectorXmlResource("drawable/ic_jio_saavn_logo.xml")) as Painter
+actual fun SpotifyLogo() =
+ getCachedPainter("drawable/ic_spotify_logo.xml")
@Composable
-actual fun YoutubeLogo() = rememberVectorPainter(vectorXmlResource("drawable/ic_youtube.xml")) as Painter
+actual fun SaavnLogo() =
+ getCachedPainter("drawable/ic_jio_saavn_logo.xml")
@Composable
-actual fun GaanaLogo() = rememberVectorPainter(vectorXmlResource("drawable/ic_gaana.xml")) as Painter
+actual fun YoutubeLogo() =
+ getCachedPainter("drawable/ic_youtube.xml")
@Composable
-actual fun YoutubeMusicLogo() = rememberVectorPainter(vectorXmlResource("drawable/ic_youtube_music_logo.xml")) as Painter
+actual fun GaanaLogo() =
+ getCachedPainter("drawable/ic_gaana.xml")
@Composable
-actual fun GithubLogo() = rememberVectorPainter(vectorXmlResource("drawable/ic_github.xml")) as Painter
+actual fun YoutubeMusicLogo() =
+ getCachedPainter("drawable/ic_youtube_music_logo.xml")
@Composable
-actual fun PaypalLogo() = rememberVectorPainter(vectorXmlResource("drawable/ic_paypal_logo.xml")) as Painter
+actual fun GithubLogo() =
+ getCachedPainter("drawable/ic_github.xml")
@Composable
-actual fun OpenCollectiveLogo() = rememberVectorPainter(vectorXmlResource("drawable/ic_opencollective_icon.xml")) as Painter
+actual fun PaypalLogo() =
+ getCachedPainter("drawable/ic_paypal_logo.xml")
@Composable
-actual fun RazorPay() = rememberVectorPainter(vectorXmlResource("drawable/ic_indian_rupee.xml")) as Painter
+actual fun OpenCollectiveLogo() =
+ getCachedPainter("drawable/ic_opencollective_icon.xml")
+
+@Composable
+actual fun RazorPay() =
+ getCachedPainter("drawable/ic_indian_rupee.xml")
diff --git a/common/data-models/src/androidMain/kotlin/com.shabinder.common.models/AndroidPlatformActions.kt b/common/data-models/src/androidMain/kotlin/com.shabinder.common.models/AndroidPlatformActions.kt
index 15b53d32..1772e88c 100644
--- a/common/data-models/src/androidMain/kotlin/com.shabinder.common.models/AndroidPlatformActions.kt
+++ b/common/data-models/src/androidMain/kotlin/com.shabinder.common.models/AndroidPlatformActions.kt
@@ -1,6 +1,7 @@
package com.shabinder.common.models
import android.content.SharedPreferences
+import kotlinx.coroutines.CoroutineScope
actual interface PlatformActions {
@@ -26,3 +27,5 @@ internal actual val StubPlatformActions = object : PlatformActions {
override fun sendTracksToService(array: List) {}
}
+
+actual fun runBlocking(block: suspend CoroutineScope.() -> T): T = kotlinx.coroutines.runBlocking { block() }
\ No newline at end of file
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/caching/Cache.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/caching/Cache.kt
index 8882b7ae..6130419d 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/caching/Cache.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/caching/Cache.kt
@@ -1,6 +1,7 @@
package com.shabinder.common.caching
import kotlin.time.Duration
+import kotlin.time.ExperimentalTime
import kotlin.time.TimeSource
/**
@@ -23,6 +24,8 @@ public interface Cache {
*/
public suspend fun get(key: Key, loader: suspend () -> Value): Value
+ public fun getBlocking(key: Key, loader: suspend () -> Value): Value
+
/**
* Associates [value] with [key] in this cache. If the cache previously contained a
* value associated with [key], the old value is replaced by [value].
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/caching/RealCache.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/caching/RealCache.kt
index 6e0cf498..593c3e4a 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/caching/RealCache.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/caching/RealCache.kt
@@ -4,6 +4,7 @@ import co.touchlab.stately.collections.IsoMutableMap
import co.touchlab.stately.collections.IsoMutableSet
import co.touchlab.stately.concurrency.AtomicReference
import co.touchlab.stately.concurrency.value
+import com.shabinder.common.models.runBlocking
import kotlin.time.Duration
import kotlin.time.TimeMark
import kotlin.time.TimeSource
@@ -110,6 +111,12 @@ internal class RealCache(
}
}
+
+ override fun getBlocking(key: Key, loader: suspend () -> Value): Value =
+ runBlocking {
+ get(key, loader)
+ }
+
override fun put(key: Key, value: Value) {
expireEntries()
@@ -185,7 +192,7 @@ internal class RealCache(
*/
private fun CacheEntry.isExpired(): Boolean {
return expiresAfterAccess && (accessTimeMark.get() + expireAfterAccessDuration).hasPassedNow() ||
- expiresAfterWrite && (writeTimeMark.get() + expireAfterWriteDuration).hasPassedNow()
+ expiresAfterWrite && (writeTimeMark.get() + expireAfterWriteDuration).hasPassedNow()
}
/**
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/PlatformActions.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/PlatformActions.kt
index 8fd73462..8454b0f7 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/PlatformActions.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/PlatformActions.kt
@@ -1,5 +1,9 @@
package com.shabinder.common.models
+import kotlinx.coroutines.CoroutineScope
+
expect interface PlatformActions
internal expect val StubPlatformActions: PlatformActions
+
+expect fun runBlocking(block: suspend CoroutineScope.() -> T): T
\ No newline at end of file
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/utils/Ext.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/utils/Ext.kt
index d7d30684..6164033f 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/utils/Ext.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/utils/Ext.kt
@@ -7,7 +7,6 @@ import kotlin.contracts.contract
fun T?.requireNotNull(): T = requireNotNull(this)
-
@OptIn(ExperimentalContracts::class)
inline fun buildString(track: TrackDetails, builderAction: StringBuilder.() -> Unit): String {
contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) }
diff --git a/common/data-models/src/desktopMain/kotlin/com/shabinder/common/models/DesktopPlatformActions.kt b/common/data-models/src/desktopMain/kotlin/com/shabinder/common/models/DesktopPlatformActions.kt
index 5386a96c..42b09eed 100644
--- a/common/data-models/src/desktopMain/kotlin/com/shabinder/common/models/DesktopPlatformActions.kt
+++ b/common/data-models/src/desktopMain/kotlin/com/shabinder/common/models/DesktopPlatformActions.kt
@@ -1,5 +1,9 @@
package com.shabinder.common.models
+import kotlinx.coroutines.CoroutineScope
+
actual interface PlatformActions
internal actual val StubPlatformActions = object : PlatformActions {}
+
+actual fun runBlocking(block: suspend CoroutineScope.() -> T): T = kotlinx.coroutines.runBlocking { block() }
\ No newline at end of file
diff --git a/common/data-models/src/jsMain/kotlin/com.shabinder.common.models/JSPlatformActions.kt b/common/data-models/src/jsMain/kotlin/com.shabinder.common.models/JSPlatformActions.kt
index 8e1f948e..56362479 100644
--- a/common/data-models/src/jsMain/kotlin/com.shabinder.common.models/JSPlatformActions.kt
+++ b/common/data-models/src/jsMain/kotlin/com.shabinder.common.models/JSPlatformActions.kt
@@ -1,5 +1,10 @@
package com.shabinder.common.models
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.promise
+
actual interface PlatformActions
-internal actual val StubPlatformActions = object : PlatformActions {}
\ No newline at end of file
+internal actual val StubPlatformActions = object : PlatformActions {}
+actual fun runBlocking(block: suspend CoroutineScope.() -> T): dynamic = GlobalScope.promise(block = block)
\ No newline at end of file