Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.19.0] Post-release merge #100

Merged
merged 4 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/android_prod_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ jobs:
- name: Setup versionName regardless of how this action is triggered
id: version_name
run: |
WORKFLOW_INPUT=${{ steps.tramline.outputs.version_code }}
WORKFLOW_INPUT=${{ steps.tramline.outputs.version_name }}
VERSION_NAME=${WORKFLOW_INPUT:-"1.0.0"}
echo "ORG_GRADLE_PROJECT_VERSION_NAME=$VERSION_NAME" >> $GITHUB_ENV

- name: Setup versionCode regardless of how this action is triggered
id: version_code
run: |
WORKFLOW_INPUT=${{ steps.tramline.outputs.version_name }}
WORKFLOW_INPUT=${{ steps.tramline.outputs.version_code }}
VERSION_CODE=${WORKFLOW_INPUT:-"1"}
echo "ORG_GRADLE_PROJECT_VERSION_CODE=$VERSION_CODE" >> $GITHUB_ENV

Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ androidx_test_rules = "1.5.0"
androidx_work = "2.8.1"
androidx_datastore = "1.1.0-alpha05"
androidx_browser = "1.6.0"
coil = "2.4.0"
spotless = "6.21.0"
ktfmt = "0.44"
kotlininject = "0.6.3"
Expand All @@ -41,7 +42,6 @@ lyricist = "1.4.2"
atomicfu = "0.22.0"
okio = "3.5.0"
paging = "3.2.0-alpha05-0.2.3"
imageloader = "1.6.7"

[libraries]
compose_runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose" }
Expand Down Expand Up @@ -80,6 +80,7 @@ androidx_work = { module = "androidx.work:work-runtime-ktx", version.ref = "andr
androidx_datastore_okio = { module = "androidx.datastore:datastore-core-okio", version.ref = "androidx_datastore" }
androidx_datastore_preferences = { module = "androidx.datastore:datastore-preferences-core", version.ref = "androidx_datastore" }
androidx_browser = { module = "androidx.browser:browser", version.ref = "androidx_browser" }
coil_compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" }
kotlininject-compiler = { module = 'me.tatarka.inject:kotlin-inject-compiler-ksp', version.ref = 'kotlininject' }
kotlininject-runtime = { module = 'me.tatarka.inject:kotlin-inject-runtime', version.ref = 'kotlininject' }
material_color_utilities = { module = "dev.sasikanth:material-color-utilities", version.ref = "material_color_utilities" }
Expand All @@ -93,7 +94,6 @@ lyricist-processor = { module = "cafe.adriel.lyricist:lyricist-processor", versi
okio = { module = "com.squareup.okio:okio", version.ref = "okio" }
paging-common = { module = "app.cash.paging:paging-common", version.ref = "paging" }
paging-compose = { module = "app.cash.paging:paging-compose-common", version.ref = "paging" }
imageloader = { module = "io.github.qdsfdhvh:image-loader", version.ref = "imageloader" }

[plugins]
android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" }
Expand Down
2 changes: 1 addition & 1 deletion shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ kotlin {
api(libs.okio)
implementation(libs.paging.common)
implementation(libs.paging.compose)
implementation(libs.imageloader)
}
}
val commonTest by getting {
Expand All @@ -126,6 +125,7 @@ kotlin {
api(libs.androidx.core)
implementation(libs.ktor.client.okhttp)
implementation(libs.sqldelight.driver.android)
implementation(libs.coil.compose)
api(libs.sqliteAndroid)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2023 Sasikanth Miriyampalli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sasikanth.rss.reader.components

import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale

@Composable
actual fun AsyncImage(
url: String,
contentDescription: String?,
contentScale: ContentScale,
modifier: Modifier,
) {
Box(modifier) {
coil.compose.AsyncImage(
modifier = Modifier.matchParentSize(),
model = url,
contentDescription = contentDescription,
contentScale = ContentScale.Crop
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2023 Sasikanth Miriyampalli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sasikanth.rss.reader.components

import android.content.Context
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.core.graphics.drawable.toBitmap
import coil.imageLoader
import coil.request.ImageRequest
import coil.request.SuccessResult
import coil.size.Scale
import dev.sasikanth.rss.reader.di.scopes.AppScope
import me.tatarka.inject.annotations.Inject

@Inject
@AppScope
class AndroidImageLoader(private val context: Context) : ImageLoader {

override suspend fun getImage(url: String, size: Int?): ImageBitmap? {
val requestBuilder =
ImageRequest.Builder(context)
.data(url)
.scale(Scale.FILL)
.allowHardware(false)
.memoryCacheKey("$url.dynamic_colors")

if (size != null) {
requestBuilder.size(size)
}

return when (val result = context.imageLoader.execute(requestBuilder.build())) {
is SuccessResult -> result.drawable.toBitmap().asImageBitmap()
else -> null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,11 @@
*/
package dev.sasikanth.rss.reader.di

import android.content.Context
import com.seiko.imageloader.ImageLoader
import com.seiko.imageloader.component.setupDefaultComponents
import com.seiko.imageloader.defaultImageResultMemoryCache
import com.seiko.imageloader.option.androidContext
import dev.sasikanth.rss.reader.di.scopes.AppScope
import dev.sasikanth.rss.reader.components.AndroidImageLoader
import dev.sasikanth.rss.reader.components.ImageLoader
import me.tatarka.inject.annotations.Provides
import okio.Path.Companion.toOkioPath

actual interface ImageLoaderComponent {

@Provides
@AppScope
fun providesImageLoader(context: Context): ImageLoader {
return ImageLoader {
options { androidContext(context) }
components { setupDefaultComponents() }
interceptor {
defaultImageResultMemoryCache()
diskCacheConfig {
directory(context.cacheDir.resolve("image_cache").toOkioPath())
maxSizeBytes(512L * 1024 * 1024) // 512MB
}
}
}
}
@Provides fun AndroidImageLoader.bind(): ImageLoader = this
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.extensions.compose.jetbrains.stack.Children
import com.arkivanov.decompose.extensions.compose.jetbrains.stack.animation.StackAnimation
import com.arkivanov.decompose.extensions.compose.jetbrains.stack.animation.plus
import com.arkivanov.essenty.backhandler.BackHandler
import com.seiko.imageloader.ImageLoader
import com.seiko.imageloader.LocalImageLoader
import dev.sasikanth.rss.reader.bookmarks.ui.BookmarksScreen
import dev.sasikanth.rss.reader.components.DynamicContentTheme
import dev.sasikanth.rss.reader.components.ImageLoader
import dev.sasikanth.rss.reader.components.LocalImageLoader
import dev.sasikanth.rss.reader.components.rememberDynamicColorState
import dev.sasikanth.rss.reader.home.ui.HomeScreen
import dev.sasikanth.rss.reader.repository.BrowserType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,14 @@
*/
package dev.sasikanth.rss.reader.components

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.layout.ContentScale
import com.seiko.imageloader.model.ImageRequest
import com.seiko.imageloader.option.SizeResolver
import com.seiko.imageloader.rememberImagePainter

@Composable
fun AsyncImage(
expect fun AsyncImage(
url: String,
contentDescription: String?,
contentScale: ContentScale = ContentScale.Crop,
contentScale: ContentScale = ContentScale.Fit,
modifier: Modifier = Modifier,
size: Size = Size(1024f, 1024f)
) {
val request =
remember(url) {
ImageRequest {
data(url)
size(SizeResolver(size))
}
}
val painter = rememberImagePainter(request)
Box(modifier) {
Image(
modifier = Modifier.matchParentSize(),
painter = painter,
contentDescription = contentDescription,
contentScale = contentScale,
)
}
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,8 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import com.seiko.imageloader.ImageLoader
import com.seiko.imageloader.LocalImageLoader
import com.seiko.imageloader.asImageBitmap
import com.seiko.imageloader.model.ImageRequest
import com.seiko.imageloader.model.ImageResult
import com.seiko.imageloader.option.SizeResolver
import dev.sasikanth.material.color.utilities.dynamiccolor.DynamicColor
import dev.sasikanth.material.color.utilities.dynamiccolor.MaterialDynamicColors
import dev.sasikanth.material.color.utilities.dynamiccolor.ToneDeltaConstraint
Expand All @@ -46,8 +39,6 @@ import dev.sasikanth.material.color.utilities.scheme.SchemeContent
import dev.sasikanth.material.color.utilities.score.Score
import dev.sasikanth.rss.reader.ui.AppTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext

private const val TINTED_BACKGROUND = "tinted_background"
Expand Down Expand Up @@ -288,15 +279,9 @@ class DynamicColorState(
return cached
}

val imageRequest = ImageRequest {
data(url)
size(SizeResolver(Size(128f, 128f)))
}
val imageResult =
imageLoader?.async(imageRequest)?.filterIsInstance<ImageResult.Bitmap>()?.first()

return if (imageResult != null) {
extractColorsFromImage(imageResult.bitmap.asImageBitmap())
val image = imageLoader?.getImage(url, size = 128)
return if (image != null) {
extractColorsFromImage(image)
.let { colorsMap ->
return@let if (colorsMap.isNotEmpty()) {
DynamicColors(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2023 Sasikanth Miriyampalli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sasikanth.rss.reader.components

import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.ImageBitmap

interface ImageLoader {
suspend fun getImage(url: String, size: Int?): ImageBitmap?
}

val LocalImageLoader = staticCompositionLocalOf<ImageLoader?> { null }
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package dev.sasikanth.rss.reader.di

import dev.sasikanth.rss.reader.components.ImageLoader
import dev.sasikanth.rss.reader.di.scopes.AppScope
import dev.sasikanth.rss.reader.initializers.Initializer
import dev.sasikanth.rss.reader.network.NetworkComponent
Expand All @@ -26,6 +27,8 @@ import me.tatarka.inject.annotations.Provides
abstract class SharedApplicationComponent :
DataComponent, ImageLoaderComponent, SentryComponent, NetworkComponent {

abstract val imageLoader: ImageLoader

abstract val initializers: Set<Initializer>

@Provides @AppScope fun DefaultDispatchersProvider.bind(): DispatchersProvider = this
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2023 Sasikanth Miriyampalli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sasikanth.rss.reader.components

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import io.ktor.client.request.get
import org.jetbrains.skia.Image

@Composable
actual fun AsyncImage(
url: String,
contentDescription: String?,
contentScale: ContentScale,
modifier: Modifier,
) {
Box(modifier) {
val imageState by rememberImageLoaderState(url)

when (imageState) {
is ImageLoaderState.Loaded -> {
Image(
modifier = Modifier.matchParentSize(),
bitmap = (imageState as ImageLoaderState.Loaded).image,
contentDescription = contentDescription,
contentScale = contentScale
)
}
else -> {
// TODO: Handle other cases instead of just showing blank space?
}
}
}
}
Loading