Skip to content

Commit

Permalink
add adaptive sizing of collection
Browse files Browse the repository at this point in the history
  • Loading branch information
Fethi Tewelde committed Oct 1, 2024
1 parent 31a5656 commit 22e8b0b
Show file tree
Hide file tree
Showing 15 changed files with 54 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import coil3.annotation.ExperimentalCoilApi
import coil3.compose.setSingletonImageLoaderFactory
import coil3.disk.DiskCache
import coil3.memory.MemoryCache
import coil3.network.ktor.KtorNetworkFetcherFactory
import coil3.network.ktor3.KtorNetworkFetcherFactory
import coil3.request.CachePolicy
import coil3.request.crossfade
import coil3.util.DebugLogger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.tewelde.rijksmuseum.di
import coil3.annotation.ExperimentalCoilApi
import coil3.network.CacheStrategy
import coil3.network.NetworkFetcher
import coil3.network.ktor.asNetworkClient
import coil3.network.ktor3.asNetworkClient
import com.tewelde.rijksmuseum.feature.arts.di.artsModule
import io.ktor.client.HttpClient
import org.koin.dsl.module
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@
<string name="permission_denied">Please grant storage permission.</string>
<string name="settings">Settings</string>
<string name="saving_failed">Image not saved, try again later.</string>
<string name="saving_success">Image is saved.</string>
<string name="saving_success">Image saved.</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface RijksMuseumNetworkDataSource {

suspend fun downloadImage(url: String, onDownload: (Long, Long?) -> Unit): ByteReadChannel

// TODO search by maaker: search https://www.rijksmuseum.nl/api/nl/collection?key=qhMVwCto&involvedMaker=Rembrandt+van+Rijn
// TODO search by maker: search https://www.rijksmuseum.nl/api/nl/collection?key=qhMVwCto&involvedMaker=Rembrandt+van+Rijn
// TODO search by color: search https://www.rijksmuseum.nl/api/nl/collection?key=qhMVwCto&f.normalized32Colors.hex=%23E5242B
// TODO SEARCH BY TERM: search https://www.rijksmuseum.nl/api/nl/collection?key=qhMVwCto&q=Rembrandt
// TODO search by production place: search https://www.rijksmuseum.nl/api/nl/collection?key=qhMVwCto&production.place=Amsterdam
Expand Down
5 changes: 4 additions & 1 deletion feature/arts/src/androidMain/kotlin/Utils.android.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,7 @@ actual class FileUtil(private val context: Context) {
}

actual val Art.artUrl: String
get() = this.webImage.url
get() = this.webImage.url

actual val minGridSize: Int
get() = 175
2 changes: 2 additions & 0 deletions feature/arts/src/commonMain/kotlin/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ expect fun screenHeight(): Int

expect val Art.artUrl: String

expect val minGridSize: Int

expect class FileUtil {
fun filesystem(): FileSystem?
suspend fun saveFile(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fun ArtDetail(
color: Color,
isDownloading: Boolean = false,
downloadProgress: Int = 0,
onDownloadClicked: () -> Unit,
onSave: () -> Unit,
onMaker: () -> Unit
) {
Column(
Expand All @@ -66,7 +66,7 @@ fun ArtDetail(
SheetActionRow(
isDownloading = isDownloading,
downloadProgress = downloadProgress,
onDownloadClicked = onDownloadClicked,
onSave = onSave,
)
SheetPhotoDetails(art, color)
}
Expand Down Expand Up @@ -129,15 +129,15 @@ fun PhotoDetailItem(
fun SheetActionRow(
isDownloading: Boolean,
downloadProgress: Int = 0,
onDownloadClicked: () -> Unit,
onSave: () -> Unit,
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Button(
onClick = { onDownloadClicked() },
onClick = { onSave() },
modifier = Modifier.fillMaxWidth().weight(1f),
shape = RoundedCornerShape(8.dp),
enabled = !isDownloading,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fun DetailScreenRoute(

DetailScreen(uiState, snackbarHostState, onShowSnackbar) {
when (it) {
is DetailEvent.OnDownloadClick,
is DetailEvent.OnSave,
is DetailEvent.NavigateToSettings,
is DetailEvent.PermissionErrorMessageConsumed,
is DetailEvent.SaveFailureMessageConsumed,
Expand Down Expand Up @@ -172,6 +172,7 @@ fun DetailScreen(
containerColor = MaterialTheme.colorScheme.surface,
contentColor = MaterialTheme.colorScheme.onSurface,
sheetTonalElevation = 0.dp,
sheetMaxWidth = 100000.dp, // TODO get screen size per platform
sheetContent = {
when (uiState.state) {
is State.Loading,
Expand All @@ -190,8 +191,8 @@ fun DetailScreen(
?: MaterialTheme.colorScheme.primary,
isDownloading = uiState.isDownloading,
downloadProgress = uiState.downloadProgress,
onDownloadClicked = {
onEvent(DetailEvent.OnDownloadClick(pfContext))
onSave = {
onEvent(DetailEvent.OnSave(pfContext))
},
onMaker = {},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.tewelde.rijksmuseum.feature.arts.detail
import FileUtil
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import co.touchlab.kermit.Logger
import coil3.PlatformContext
import coil3.SingletonImageLoader
import com.tewelde.rijksmuseum.core.common.Either
Expand All @@ -16,7 +17,7 @@ import com.tewelde.rijksmuseum.core.permissions.util.DeniedException
import com.tewelde.rijksmuseum.feature.arts.detail.model.DetailEvent
import com.tewelde.rijksmuseum.feature.arts.detail.model.DetailState
import com.tewelde.rijksmuseum.feature.arts.detail.model.State
import io.ktor.util.toByteArray
import io.ktor.utils.io.toByteArray
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
Expand All @@ -30,6 +31,7 @@ class DetailViewModel(
private val permissionsService: PermissionsService,
private val downloadImageUseCase: DownloadImageUseCase
) : ViewModel() {
val logger = Logger.withTag(this::class.simpleName!!)
private var _uiState = MutableStateFlow(DetailState())
val uiState: StateFlow<DetailState> = _uiState
.stateIn(
Expand All @@ -40,9 +42,9 @@ class DetailViewModel(

fun onEvent(event: DetailEvent) {
when (event) {
is DetailEvent.OnDownloadClick -> {
is DetailEvent.OnSave -> {
checkPermission {
downloadImage(event.context)
saveImage(event.context)
}
}

Expand Down Expand Up @@ -76,7 +78,7 @@ class DetailViewModel(
}
}

private fun downloadImage(context: PlatformContext) = viewModelScope.launch {
private fun saveImage(context: PlatformContext) = viewModelScope.launch {
_uiState.update { detailsState ->
detailsState.copy(
isDownloading = true
Expand All @@ -85,11 +87,14 @@ class DetailViewModel(
val imageLoader = SingletonImageLoader.get(context)
val cache = imageLoader.diskCache?.openSnapshot(art.url)
if (cache == null) {
logger.d { "#### image not found in cache, Downloading image" }
val bytes = downloadImageUseCase(art.url) { downloaded, total ->
total?.let {
_uiState.update { detailsState ->
detailsState.copy(
downloadProgress = (downloaded * 100 / total).toInt()
downloadProgress = (downloaded * 100 / total).toInt().also {
Logger.d { "#### download progress: $it" }
}
)
}
}
Expand Down Expand Up @@ -117,6 +122,7 @@ class DetailViewModel(
}
)
} else {
logger.d { "#### image found in cache" }
cache.use { snapshot ->
val data = snapshot.data
val content = fileUtil.filesystem()?.read(data) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sealed class DetailEvent {
data object NavigateToSettings : DetailEvent()
data object PermissionErrorMessageConsumed : DetailEvent()
data object SaveFailureMessageConsumed : DetailEvent()
class OnDownloadClick(val context: PlatformContext) : DetailEvent()
class OnSave(val context: PlatformContext) : DetailEvent()
class LoadDetail(val objectId: String) : DetailEvent()
data object SaveSuccessMessageConsumed : DetailEvent()
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ import com.tewelde.rijksmuseum.feature.arts.gallery.model.ArtsUiState
import com.tewelde.rijksmuseum.feature.arts.gallery.model.GalleryEvent
import com.tewelde.rijksmuseum.resources.Res
import com.tewelde.rijksmuseum.resources.arts_screen
import minGridSize
import org.jetbrains.compose.resources.stringResource
import org.jetbrains.compose.ui.tooling.preview.Preview
import artUrl

@Composable
fun CollectionScreenRoute(
Expand Down Expand Up @@ -131,7 +131,7 @@ internal fun CollectionScreen(
}

LazyVerticalStaggeredGrid(
columns = StaggeredGridCells.Fixed(2)
columns = StaggeredGridCells.Adaptive(minGridSize.dp)
) {
items(
items = uiState.filteredArts,
Expand Down
9 changes: 6 additions & 3 deletions feature/arts/src/desktopMain/kotlin/Utils.desktop.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ actual class FileUtil {
onSuccess: () -> Unit
) {
try {
FileKit.saveFile(
val file = FileKit.saveFile(
bytes = bytes,
baseName = baseName,
extension = extension,
initialDirectory = initialDirectory,
platformSettings = platformSettings
)
onSuccess()
file?.let { onSuccess() } ?: onFailure(Exception("File not saved"))
} catch (e: Exception) {
onFailure(e)
}
Expand All @@ -39,4 +39,7 @@ actual class FileUtil {
}

actual val Art.artUrl: String
get() = this.headerImage?.url ?: this.webImage.url
get() = this.headerImage?.url ?: this.webImage.url

actual val minGridSize: Int
get() = 325
15 changes: 5 additions & 10 deletions feature/arts/src/iosMain/kotlin/Utils.ios.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,20 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.platform.LocalWindowInfo
import com.tewelde.rijksmuseum.core.model.Art
import io.github.vinceglb.filekit.core.FileKit
import io.github.vinceglb.filekit.core.FileKitPlatformSettings
import io.github.vinceglb.filekit.core.PlatformFile
import kotlinx.cinterop.BetaInteropApi
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.allocArrayOf
import kotlinx.cinterop.memScoped
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import okio.FileSystem
import platform.Foundation.NSData
import platform.Foundation.NSURL
import platform.Foundation.create
import platform.UIKit.UIImage
import platform.UIKit.UIImageWriteToSavedPhotosAlbum
import kotlin.coroutines.coroutineContext
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

@OptIn(ExperimentalComposeUiApi::class)
@Composable
Expand All @@ -32,8 +25,7 @@ actual class FileUtil {
actual fun filesystem(): FileSystem? = FileSystem.SYSTEM

@OptIn(
ExperimentalForeignApi::class,
BetaInteropApi::class
ExperimentalForeignApi::class
)
actual suspend fun saveFile(
bytes: ByteArray,
Expand Down Expand Up @@ -73,4 +65,7 @@ actual class FileUtil {
}

actual val Art.artUrl: String
get() = this.webImage.url
get() = this.webImage.url

actual val minGridSize: Int
get() = 175
10 changes: 6 additions & 4 deletions feature/arts/src/wasmJsMain/kotlin/Utils.wasmJs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import androidx.compose.ui.platform.LocalWindowInfo
import com.tewelde.rijksmuseum.core.model.Art
import io.github.vinceglb.filekit.core.FileKit
import io.github.vinceglb.filekit.core.FileKitPlatformSettings
import io.github.vinceglb.filekit.core.PlatformFile
import okio.FileSystem

@OptIn(ExperimentalComposeUiApi::class)
Expand All @@ -24,14 +23,14 @@ actual class FileUtil {
onSuccess: () -> Unit
) {
try {
FileKit.saveFile(
val file = FileKit.saveFile(
bytes = bytes,
baseName = baseName,
extension = extension,
initialDirectory = initialDirectory,
platformSettings = platformSettings
)
onSuccess()
file?.let { onSuccess() } ?: onFailure(Exception("File not saved"))
} catch (e: Exception) {
onFailure(e)
}
Expand All @@ -42,4 +41,7 @@ actual class FileUtil {
}

actual val Art.artUrl: String
get() = this.headerImage?.url ?: this.webImage.url
get() = this.headerImage?.url ?: this.webImage.url

actual val minGridSize: Int
get() = 325
11 changes: 5 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ androidx-core-ktx = "1.13.1"
androidx-espresso-core = "3.6.1"
androidx-material = "1.12.0"
androidx-test-junit = "1.2.1"
coil = "3.0.0-alpha10"
coilNetworkKtor = "3.0.0-alpha08"
coil= "3.0.0-alpha10"
compose-plugin = "1.6.11"
filekit = "0.8.3"
junit = "4.13.2"
kotlin = "2.0.20"
koin = "4.0.0"
koinComposeMultiplatform = "4.0.0"
ktor = "3.0.0-wasm2"
ktor = "3.0.0-rc-1"
lifecycle = "2.8.2"
navigationCompose = "2.7.0-alpha07"
kotlinx_serialization_json = "1.7.3"
Expand All @@ -32,7 +31,7 @@ kermit = "2.0.4"
androidx-lifecycle-viewmodel = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
androidx-lifecycle-runtimeCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle" }
coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" }
coil-network-ktor = { module = "io.coil-kt.coil3:coil-network-ktor", version.ref = "coilNetworkKtor" }
coil-network-ktor = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil" }
coil_compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
filekit-core = { module = "io.github.vinceglb:filekit-core", version.ref = "filekit" }
coil_compose_core = { module = "io.coil-kt.coil3:coil-compose-core", version.ref = "coil" }
Expand Down Expand Up @@ -86,5 +85,5 @@ buildConfig = { id = "com.github.gmazzo.buildconfig", version.ref = "buildConfig


# Plugins defined by this project
rijksmuseum-composeMultiplatform = { id = "com.tewelde.rijksmuseum.composeMultiplatform" }
rijksmuseum-kotlinMultiplatform = { id = "com.tewelde.rijksmuseum.kotlinMultiplatform" }
rijksmuseum-composeMultiplatform = { id = "com.tewelde.rijksmuseum.composeMultiplatform", version = "unspecified" }
rijksmuseum-kotlinMultiplatform = { id = "com.tewelde.rijksmuseum.kotlinMultiplatform", version = "unspecified" }

0 comments on commit 22e8b0b

Please sign in to comment.