Picture Class & Compose Setup Fixed

This commit is contained in:
shabinder 2021-03-06 23:03:05 +05:30
parent 176141bed5
commit 3ce1dfffbd
24 changed files with 171 additions and 67 deletions

View File

@ -7,10 +7,6 @@ plugins {
kotlin { kotlin {
jvm("desktop") jvm("desktop")
android() android()
js {
browser()
nodejs()
}
sourceSets { sourceSets {
named("commonMain") { named("commonMain") {
dependencies { dependencies {
@ -32,13 +28,6 @@ kotlin {
implementation(compose.desktop.common) implementation(compose.desktop.common)
} }
} }
named("jsMain") {
dependencies {
implementation("org.jetbrains:kotlin-react:17.0.1-pre.148-kotlin-1.4.30")
implementation("org.jetbrains:kotlin-styled:1.0.0-pre.115-kotlin-1.4.10")
implementation("org.jetbrains:kotlin-react-dom:17.0.1-pre.148-kotlin-1.4.30")
}
}
} }
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> { tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {

View File

@ -0,0 +1,42 @@
plugins {
id("com.android.library")
id("kotlin-multiplatform")
}
kotlin {
jvm("desktop")
android()
//ios()
js {
browser()
nodejs()
}
sourceSets {
named("commonTest") {
dependencies {
implementation(JetBrains.Kotlin.testCommon)
implementation(JetBrains.Kotlin.testAnnotationsCommon)
}
}
named("androidTest") {
dependencies {
implementation(JetBrains.Kotlin.testJunit)
}
}
named("desktopTest") {
dependencies {
implementation(JetBrains.Kotlin.testJunit)
}
}
named("jsTest") {
dependencies {
}
}
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
}

View File

@ -1,37 +1,47 @@
import gradle.kotlin.dsl.accessors._2e23d8fadf0ed92ae13e19db3d83f86d.compose
import gradle.kotlin.dsl.accessors._2e23d8fadf0ed92ae13e19db3d83f86d.kotlin
import gradle.kotlin.dsl.accessors._2e23d8fadf0ed92ae13e19db3d83f86d.sourceSets
import org.gradle.kotlin.dsl.withType
plugins { plugins {
id("com.android.library") id("com.android.library")
id("kotlin-multiplatform") id("kotlin-multiplatform")
id("org.jetbrains.compose")
} }
kotlin { kotlin {
jvm("desktop") jvm("desktop")
android() android()
//ios()
js { js {
browser() browser()
nodejs() nodejs()
} }
sourceSets { sourceSets {
named("commonTest") { named("commonMain") {
dependencies { dependencies {
implementation(JetBrains.Kotlin.testCommon) implementation(compose.runtime)
implementation(JetBrains.Kotlin.testAnnotationsCommon) implementation(compose.foundation)
implementation(compose.material)
} }
} }
named("androidTest") { named("androidMain") {
dependencies { dependencies {
implementation(JetBrains.Kotlin.testJunit) implementation("androidx.appcompat:appcompat:1.2.0")
implementation(Androidx.core)
} }
} }
named("desktopTest") {
dependencies {
implementation(JetBrains.Kotlin.testJunit)
}
}
named("jsTest") {
dependencies {
named("desktopMain") {
dependencies {
implementation(compose.desktop.common)
}
}
named("jsMain") {
dependencies {
implementation("org.jetbrains:kotlin-react:17.0.1-pre.148-kotlin-1.4.30")
implementation("org.jetbrains:kotlin-styled:1.0.0-pre.115-kotlin-1.4.10")
implementation("org.jetbrains:kotlin-react-dom:17.0.1-pre.148-kotlin-1.4.30")
} }
} }
} }

View File

@ -3,16 +3,36 @@
package com.shabinder.common.uikit package com.shabinder.common.uikit
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import com.shabinder.common.database.R import com.shabinder.common.database.R
import com.shabinder.common.di.Picture
import com.shabinder.common.di.dispatcherIO
import kotlinx.coroutines.withContext
@Composable
actual fun ImageLoad(link:String, loader:suspend (String) -> Picture, desc: String, modifier:Modifier, placeholder: ImageVector) {
var pic by remember(link) { mutableStateOf<ImageBitmap?>(null) }
LaunchedEffect(link){
withContext(dispatcherIO) {
pic = loader(link).image
}
}
Crossfade(pic){
if(it == null) Image(placeholder, desc, modifier,contentScale = ContentScale.Crop) else Image(it, desc, modifier,contentScale = ContentScale.Crop)
}
}
actual fun montserratFont() = FontFamily( actual fun montserratFont() = FontFamily(
Font(R.font.montserrat_light, FontWeight.Light), Font(R.font.montserrat_light, FontWeight.Light),

View File

@ -1,28 +1,19 @@
@file:Suppress("FunctionName") @file:Suppress("FunctionName")
package com.shabinder.common.uikit package com.shabinder.common.uikit
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.Image
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale import com.shabinder.common.di.Picture
import com.shabinder.common.di.dispatcherIO
import kotlinx.coroutines.withContext
@Composable @Composable
fun ImageLoad(link:String,loader:suspend (String) ->ImageBitmap?, desc: String = "Album Art", modifier:Modifier = Modifier, placeholder:ImageVector = PlaceHolderImage()) { expect fun ImageLoad(
var pic by remember(link) { mutableStateOf<ImageBitmap?>(null) } link:String,
LaunchedEffect(link){ loader:suspend (String) ->Picture,
withContext(dispatcherIO) { desc: String = "Album Art",
pic = loader(link) modifier:Modifier = Modifier,
} placeholder:ImageVector = PlaceHolderImage()
} )
Crossfade(pic){
if(it == null) Image(placeholder, desc, modifier,contentScale = ContentScale.Crop) else Image(it, desc, modifier,contentScale = ContentScale.Crop)
}
}
@Composable @Composable
expect fun DownloadImageTick() expect fun DownloadImageTick()

View File

@ -1,14 +1,35 @@
@file:Suppress("FunctionName") @file:Suppress("FunctionName")
package com.shabinder.common.uikit package com.shabinder.common.uikit
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.vectorXmlResource import androidx.compose.ui.res.vectorXmlResource
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.platform.Font import androidx.compose.ui.text.platform.Font
import com.shabinder.common.di.Picture
import com.shabinder.common.di.dispatcherIO
import kotlinx.coroutines.withContext
@Composable
actual fun ImageLoad(link:String, loader:suspend (String) -> Picture, desc: String, modifier:Modifier, placeholder: ImageVector) {
var pic by remember(link) { mutableStateOf<ImageBitmap?>(null) }
LaunchedEffect(link){
withContext(dispatcherIO) {
pic = loader(link).image
}
}
Crossfade(pic){
if(it == null) Image(placeholder, desc, modifier,contentScale = ContentScale.Crop) else Image(it, desc, modifier,contentScale = ContentScale.Crop)
}
}
@Composable @Composable
actual fun DownloadImageTick(){ actual fun DownloadImageTick(){

View File

@ -1,5 +1,5 @@
plugins { plugins {
id("multiplatform-setup") id("multiplatform-setup-test")
id("android-setup") id("android-setup")
id("com.squareup.sqldelight") id("com.squareup.sqldelight")
} }

View File

@ -1,7 +1,7 @@
import org.jetbrains.compose.compose import org.jetbrains.compose.compose
plugins { plugins {
id("multiplatform-compose-setup") id("multiplatform-setup")
id("android-setup") id("android-setup")
kotlin("plugin.serialization") kotlin("plugin.serialization")
} }
@ -11,8 +11,8 @@ kotlin {
commonMain { commonMain {
dependencies { dependencies {
implementation(compose.materialIconsExtended) implementation(compose.materialIconsExtended)
implementation(project(":common:data-models")) api(project(":common:data-models"))
implementation(project(":common:database")) api(project(":common:database"))
implementation(project(":fuzzywuzzy:app")) implementation(project(":fuzzywuzzy:app"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0")
@ -47,5 +47,10 @@ kotlin {
implementation(Ktor.slf4j) implementation(Ktor.slf4j)
} }
} }
jsMain {
dependencies {
implementation(project(":common:data-models"))
}
}
} }
} }

View File

@ -136,9 +136,9 @@ actual class Dir actual constructor(
listOf(path).toTypedArray(), null,null) listOf(path).toTypedArray(), null,null)
} }
actual suspend fun loadImage(url: String): ImageBitmap? { actual suspend fun loadImage(url: String): Picture {
val cachePath = imageCacheDir() + getNameURL(url) val cachePath = imageCacheDir() + getNameURL(url)
return (loadCachedImage(cachePath) ?: freshImage(url))?.asImageBitmap() return Picture(image = (loadCachedImage(cachePath) ?: freshImage(url))?.asImageBitmap())
} }
private fun loadCachedImage(cachePath: String): Bitmap? { private fun loadCachedImage(cachePath: String): Bitmap? {

View File

@ -0,0 +1,7 @@
package com.shabinder.common.di
import androidx.compose.ui.graphics.ImageBitmap
actual data class Picture (
var image: ImageBitmap?
)

View File

@ -1,6 +1,5 @@
package com.shabinder.common.di package com.shabinder.common.di
import androidx.compose.ui.graphics.ImageBitmap
import co.touchlab.kermit.Kermit import co.touchlab.kermit.Kermit
import com.shabinder.common.models.DownloadResult import com.shabinder.common.models.DownloadResult
import com.shabinder.common.models.TrackDetails import com.shabinder.common.models.TrackDetails
@ -20,7 +19,7 @@ expect class Dir(
fun imageCacheDir(): String fun imageCacheDir(): String
fun createDirectory(dirPath:String) fun createDirectory(dirPath:String)
suspend fun cacheImage(image: Any,path: String) // in Android = ImageBitmap, Desktop = BufferedImage suspend fun cacheImage(image: Any,path: String) // in Android = ImageBitmap, Desktop = BufferedImage
suspend fun loadImage(url:String): ImageBitmap? suspend fun loadImage(url:String): Picture
suspend fun clearCache() suspend fun clearCache()
suspend fun saveFileWithMetadata(mp3ByteArray: ByteArray, trackDetails: TrackDetails) suspend fun saveFileWithMetadata(mp3ByteArray: ByteArray, trackDetails: TrackDetails)
fun addToLibrary(path:String) fun addToLibrary(path:String)

View File

@ -0,0 +1,3 @@
package com.shabinder.common.di
expect class Picture

View File

@ -18,6 +18,9 @@ import java.net.HttpURLConnection
import java.net.URL import java.net.URL
import javax.imageio.ImageIO import javax.imageio.ImageIO
actual class Dir actual constructor(private val logger: Kermit) { actual class Dir actual constructor(private val logger: Kermit) {
init { init {
@ -79,11 +82,12 @@ actual class Dir actual constructor(private val logger: Kermit) {
.setId3v2TagsAndSaveFile(trackDetails) .setId3v2TagsAndSaveFile(trackDetails)
} }
actual fun addToLibrary(path:String){} actual fun addToLibrary(path:String){}
actual suspend fun loadImage(url: String): ImageBitmap? {
actual suspend fun loadImage(url: String): Picture {
val cachePath = imageCacheDir() + getNameURL(url) val cachePath = imageCacheDir() + getNameURL(url)
var picture: ImageBitmap? = loadCachedImage(cachePath) var picture: ImageBitmap? = loadCachedImage(cachePath)
if (picture == null) picture = freshImage(url) if (picture == null) picture = freshImage(url)
return picture return Picture(image = picture)
} }
private fun loadCachedImage(cachePath: String): ImageBitmap? { private fun loadCachedImage(cachePath: String): ImageBitmap? {

View File

@ -0,0 +1,7 @@
package com.shabinder.common.di
import androidx.compose.ui.graphics.ImageBitmap
actual data class Picture(
var image: ImageBitmap?
)

View File

@ -2,9 +2,6 @@ package com.shabinder.common.di
import co.touchlab.kermit.Kermit import co.touchlab.kermit.Kermit
import com.shabinder.common.models.TrackDetails import com.shabinder.common.models.TrackDetails
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.w3c.dom.ImageBitmap import org.w3c.dom.ImageBitmap
actual class Dir actual constructor(private val logger: Kermit) { actual class Dir actual constructor(private val logger: Kermit) {
@ -43,8 +40,8 @@ actual class Dir actual constructor(private val logger: Kermit) {
actual fun addToLibrary(path:String){} actual fun addToLibrary(path:String){}
actual suspend fun loadImage(url: String): ImageBitmap? { actual suspend fun loadImage(url: String): Picture {
return null return Picture(url)
} }
private fun loadCachedImage(cachePath: String): ImageBitmap? { private fun loadCachedImage(cachePath: String): ImageBitmap? {

View File

@ -0,0 +1,5 @@
package com.shabinder.common.di
actual data class Picture(
var imageUrl:String
)

View File

@ -1,5 +1,5 @@
plugins { plugins {
id("multiplatform-compose-setup") id("multiplatform-setup")
id("android-setup") id("android-setup")
id("kotlin-parcelize") id("kotlin-parcelize")
} }

View File

@ -5,6 +5,7 @@ import com.arkivanov.decompose.ComponentContext
import com.arkivanov.mvikotlin.core.store.StoreFactory import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.shabinder.common.di.Dir import com.shabinder.common.di.Dir
import com.shabinder.common.di.FetchPlatformQueryResult import com.shabinder.common.di.FetchPlatformQueryResult
import com.shabinder.common.di.Picture
import com.shabinder.common.list.integration.SpotiFlyerListImpl import com.shabinder.common.list.integration.SpotiFlyerListImpl
import com.shabinder.common.models.Consumer import com.shabinder.common.models.Consumer
import com.shabinder.common.models.DownloadStatus import com.shabinder.common.models.DownloadStatus
@ -35,7 +36,7 @@ interface SpotiFlyerList {
/* /*
* Load Image from cache/Internet and cache it * Load Image from cache/Internet and cache it
* */ * */
suspend fun loadImage(url:String): ImageBitmap? suspend fun loadImage(url:String): Picture
/* /*
* Sync Tracks Statuses * Sync Tracks Statuses

View File

@ -3,6 +3,7 @@ package com.shabinder.common.list.integration
import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.ImageBitmap
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.arkivanov.mvikotlin.extensions.coroutines.states import com.arkivanov.mvikotlin.extensions.coroutines.states
import com.shabinder.common.di.Picture
import com.shabinder.common.list.SpotiFlyerList import com.shabinder.common.list.SpotiFlyerList
import com.shabinder.common.list.SpotiFlyerList.Dependencies import com.shabinder.common.list.SpotiFlyerList.Dependencies
import com.shabinder.common.list.SpotiFlyerList.State import com.shabinder.common.list.SpotiFlyerList.State
@ -46,5 +47,5 @@ internal class SpotiFlyerListImpl(
store.accept(Intent.RefreshTracksStatuses) store.accept(Intent.RefreshTracksStatuses)
} }
override suspend fun loadImage(url: String): ImageBitmap? = dir.loadImage(url) override suspend fun loadImage(url: String): Picture = dir.loadImage(url)
} }

View File

@ -1,7 +1,7 @@
import org.jetbrains.compose.compose import org.jetbrains.compose.compose
plugins { plugins {
id("multiplatform-compose-setup") id("multiplatform-setup")
id("android-setup") id("android-setup")
id("kotlin-parcelize") id("kotlin-parcelize")
} }

View File

@ -4,6 +4,7 @@ import androidx.compose.ui.graphics.ImageBitmap
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.arkivanov.mvikotlin.core.store.StoreFactory import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.shabinder.common.di.Dir import com.shabinder.common.di.Dir
import com.shabinder.common.di.Picture
import com.shabinder.common.main.integration.SpotiFlyerMainImpl import com.shabinder.common.main.integration.SpotiFlyerMainImpl
import com.shabinder.common.models.Consumer import com.shabinder.common.models.Consumer
import com.shabinder.common.models.DownloadRecord import com.shabinder.common.models.DownloadRecord
@ -33,7 +34,7 @@ interface SpotiFlyerMain {
/* /*
* Load Image from cache/Internet and cache it * Load Image from cache/Internet and cache it
* */ * */
suspend fun loadImage(url:String): ImageBitmap? suspend fun loadImage(url:String): Picture
interface Dependencies { interface Dependencies {
val mainOutput: Consumer<Output> val mainOutput: Consumer<Output>

View File

@ -3,6 +3,7 @@ package com.shabinder.common.main.integration
import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.ImageBitmap
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.arkivanov.mvikotlin.extensions.coroutines.states import com.arkivanov.mvikotlin.extensions.coroutines.states
import com.shabinder.common.di.Picture
import com.shabinder.common.di.isInternetAvailable import com.shabinder.common.di.isInternetAvailable
import com.shabinder.common.di.showPopUpMessage import com.shabinder.common.di.showPopUpMessage
import com.shabinder.common.main.SpotiFlyerMain import com.shabinder.common.main.SpotiFlyerMain
@ -40,5 +41,5 @@ internal class SpotiFlyerMainImpl(
store.accept(Intent.SelectCategory(category)) store.accept(Intent.SelectCategory(category))
} }
override suspend fun loadImage(url: String): ImageBitmap? = dir.loadImage(url) override suspend fun loadImage(url: String): Picture = dir.loadImage(url)
} }

View File

@ -1,7 +1,7 @@
import org.jetbrains.compose.compose import org.jetbrains.compose.compose
plugins { plugins {
id("multiplatform-compose-setup") id("multiplatform-setup")
id("android-setup") id("android-setup")
id("kotlin-parcelize") id("kotlin-parcelize")
} }