Rewrite FeedColors with some tests
This commit is contained in:
parent
d1e170a1b8
commit
d97da320b4
@ -72,6 +72,7 @@ dependencies {
|
|||||||
implementation composeBom
|
implementation composeBom
|
||||||
androidTestImplementation composeBom
|
androidTestImplementation composeBom
|
||||||
|
|
||||||
|
implementation 'androidx.palette:palette-ktx:1.0.0'
|
||||||
implementation 'androidx.activity:activity-compose:1.7.2'
|
implementation 'androidx.activity:activity-compose:1.7.2'
|
||||||
implementation 'androidx.compose.material3:material3'
|
implementation 'androidx.compose.material3:material3'
|
||||||
|
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.readrops.app.compose
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.test.core.app.ApplicationProvider
|
||||||
|
import com.readrops.api.apiModule
|
||||||
|
import com.readrops.api.utils.ApiUtils
|
||||||
|
import com.readrops.app.compose.utils.FeedColors
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import okhttp3.mockwebserver.MockResponse
|
||||||
|
import okhttp3.mockwebserver.MockWebServer
|
||||||
|
import okio.Buffer
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.koin.dsl.module
|
||||||
|
import org.koin.test.KoinTestRule
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
class FeedColorsTest {
|
||||||
|
|
||||||
|
private val mockServer = MockWebServer()
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun before() {
|
||||||
|
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||||
|
|
||||||
|
KoinTestRule.create {
|
||||||
|
modules(apiModule, module {
|
||||||
|
single { context }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
mockServer.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun after() {
|
||||||
|
mockServer.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getFeedColorTest() = runBlocking {
|
||||||
|
val stream = TestUtils.loadResource("favicon.ico")
|
||||||
|
|
||||||
|
mockServer.enqueue(
|
||||||
|
MockResponse()
|
||||||
|
.setResponseCode(HttpURLConnection.HTTP_OK)
|
||||||
|
.addHeader(ApiUtils.CONTENT_TYPE_HEADER, "image/jpeg")
|
||||||
|
.setBody(Buffer().readFrom(stream))
|
||||||
|
)
|
||||||
|
|
||||||
|
val url = mockServer.url("/rss").toString()
|
||||||
|
val color = FeedColors.getFeedColor(url)
|
||||||
|
|
||||||
|
assertTrue { color != 0 }
|
||||||
|
}
|
||||||
|
}
|
BIN
appcompose/src/androidTest/resources/favicon.ico
Normal file
BIN
appcompose/src/androidTest/resources/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
@ -1,14 +1,18 @@
|
|||||||
package com.readrops.app.compose
|
package com.readrops.app.compose
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import coil.ImageLoader
|
||||||
|
import coil.ImageLoaderFactory
|
||||||
import com.readrops.api.apiModule
|
import com.readrops.api.apiModule
|
||||||
import com.readrops.db.dbModule
|
import com.readrops.db.dbModule
|
||||||
import org.koin.android.ext.koin.androidContext
|
import org.koin.android.ext.koin.androidContext
|
||||||
import org.koin.android.ext.koin.androidLogger
|
import org.koin.android.ext.koin.androidLogger
|
||||||
|
import org.koin.core.component.KoinComponent
|
||||||
|
import org.koin.core.component.get
|
||||||
import org.koin.core.context.startKoin
|
import org.koin.core.context.startKoin
|
||||||
import org.koin.core.logger.Level
|
import org.koin.core.logger.Level
|
||||||
|
|
||||||
open class ReadropsApp : Application() {
|
open class ReadropsApp : Application(), KoinComponent, ImageLoaderFactory {
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
@ -20,4 +24,11 @@ open class ReadropsApp : Application() {
|
|||||||
modules(apiModule, dbModule, composeAppModule)
|
modules(apiModule, dbModule, composeAppModule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun newImageLoader(): ImageLoader {
|
||||||
|
return ImageLoader.Builder(this)
|
||||||
|
.okHttpClient { get() }
|
||||||
|
.crossfade(true)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.readrops.app.compose.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import androidx.annotation.ColorInt
|
||||||
|
import androidx.palette.graphics.Palette
|
||||||
|
import coil.imageLoader
|
||||||
|
import coil.request.ImageRequest
|
||||||
|
import org.koin.core.component.KoinComponent
|
||||||
|
import org.koin.core.component.get
|
||||||
|
|
||||||
|
object FeedColors : KoinComponent {
|
||||||
|
|
||||||
|
suspend fun getFeedColor(feedUrl: String): Int {
|
||||||
|
val context = get<Context>() // TODO maybe call imageLoader directly ? may require some DI changes
|
||||||
|
|
||||||
|
val result = context.imageLoader
|
||||||
|
.execute(
|
||||||
|
ImageRequest.Builder(context)
|
||||||
|
.data(feedUrl)
|
||||||
|
.allowHardware(false)
|
||||||
|
.build()
|
||||||
|
).drawable as BitmapDrawable
|
||||||
|
|
||||||
|
val palette = Palette.from(result.bitmap).generate()
|
||||||
|
|
||||||
|
val dominantSwatch = palette.dominantSwatch
|
||||||
|
return if (dominantSwatch != null && !isColorTooBright(dominantSwatch.rgb)
|
||||||
|
&& !isColorTooDark(dominantSwatch.rgb)) {
|
||||||
|
dominantSwatch.rgb
|
||||||
|
} else 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isColorTooBright(@ColorInt color: Int): Boolean {
|
||||||
|
return getColorLuma(color) > 210
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isColorTooDark(@ColorInt color: Int): Boolean {
|
||||||
|
return getColorLuma(color) < 40
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getColorLuma(@ColorInt color: Int): Double {
|
||||||
|
val r = color shr 16 and 0xff
|
||||||
|
val g = color shr 8 and 0xff
|
||||||
|
val b = color shr 0 and 0xff
|
||||||
|
return 0.2126 * r + 0.7152 * g + 0.0722 * b
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user