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

Immutable collections for compose code #364

Merged
merged 1 commit into from
Feb 8, 2025
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
119 changes: 119 additions & 0 deletions core/ui/src/main/java/ru/stersh/youamp/core/ui/Playlist.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package ru.stersh.youamp.core.ui

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Album
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.dp


@Composable
fun PlaylistItem(
title: String,
onClick: () -> Unit,
artworkUrl: String? = null,
playButton: @Composable () -> Unit = {},
modifier: Modifier = Modifier
) {
ElevatedCard(
shape = MaterialTheme.shapes.large,
onClick = onClick,
modifier = modifier
) {
PlaylistLayout(
title = {
Text(
text = title,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Left,
minLines = 1,
maxLines = 1,
style = MaterialTheme.typography.labelLarge
)
},
artwork = {
Artwork(
artworkUrl = artworkUrl,
placeholder = Icons.Rounded.Album
)
},
playButton = playButton
)
}
}

@Composable
private fun PlaylistLayout(
title: @Composable () -> Unit,
artwork: @Composable () -> Unit,
playButton: @Composable () -> Unit,
modifier: Modifier = Modifier
) {
val density = LocalDensity.current
val contentPadding = 12.dp.roundToPx(density)
val titleTopPadding = 4.dp.roundToPx(density)
Layout(
contents = listOf(
title,
artwork,
playButton
),
modifier = modifier
) { measurables, constraints ->

val titlePlaceable = measurables[0]
.first()
.measure(constraints)
val artworkPlaceable = measurables[1]
.first()
.measure(Constraints.fixed(constraints.maxWidth, constraints.maxWidth))
val playButtonPlaceable = measurables
.getOrNull(2)
?.firstOrNull()
?.measure(constraints)

val maxHeight =
titlePlaceable.height + artworkPlaceable.height + titleTopPadding + contentPadding + ((playButtonPlaceable?.height
?: 0) / 2)

layout(artworkPlaceable.width, maxHeight) {
artworkPlaceable.placeRelative(0, 0)
playButtonPlaceable?.placeRelative(
(artworkPlaceable.width / 2) - (playButtonPlaceable.width / 2),
artworkPlaceable.height - (playButtonPlaceable.height / 2)
)
val titleY = if (playButtonPlaceable != null) {
artworkPlaceable.height + titleTopPadding + (playButtonPlaceable.height / 2)
} else {
artworkPlaceable.height + titleTopPadding
}
titlePlaceable.placeRelative(contentPadding, titleY)
}
}
}

@Composable
@Preview
private fun PlaylistItemPreview() {
MaterialTheme {
PlaylistItem(
title = "Playlist",
playButton = {
PlayButtonOutlined(
isPlaying = false,
onClick = {},
)
},
onClick = {}
)
}
}
1 change: 1 addition & 0 deletions feature/album/favorites/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ dependencies {
implementation(libs.coil.compose)
implementation(libs.bundles.koin)
implementation(libs.timber)
implementation(libs.immutableCollections)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.collections.immutable.persistentListOf
import org.koin.androidx.compose.koinViewModel
import ru.stersh.youamp.core.ui.AlbumItem
import ru.stersh.youamp.core.ui.BackNavigationButton
Expand Down Expand Up @@ -168,7 +169,7 @@ private fun Progress() {
@Composable
private fun FavoriteAlbumsScreenPreview() {
MaterialTheme {
val albums = listOf(
val albums = persistentListOf(
AlbumUi(
id = "1",
title = "Best alubm in the world 1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package ru.stresh.youamp.feature.album.favorites.ui

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -74,6 +76,7 @@ internal class FavoriteAlbumsViewModel(
favoriteAlbumsRepository
.getFavorites()
.map { it.toUi() }
.flowOn(Dispatchers.IO)
.catch { throwable ->
Timber.w(throwable)
_state.update {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package ru.stresh.youamp.feature.album.favorites.ui

import kotlinx.collections.immutable.toImmutableList
import ru.stresh.youamp.feature.album.favorites.domain.Album
import ru.stresh.youamp.feature.album.favorites.domain.Favorites

internal fun Favorites.toUi(): DataUi {
return DataUi(
albums = albums.map { it.toUi() }
albums = albums
.map { it.toUi() }
.toImmutableList()
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ru.stresh.youamp.feature.album.favorites.ui

import androidx.compose.runtime.Immutable
import kotlinx.collections.immutable.ImmutableList

internal data class StateUi(
val progress: Boolean = true,
Expand All @@ -9,9 +9,8 @@ internal data class StateUi(
val data: DataUi? = null
)

@Immutable
internal data class DataUi(
val albums: List<AlbumUi>
val albums: ImmutableList<AlbumUi>
)

internal class AlbumUi(
Expand Down
1 change: 1 addition & 0 deletions feature/album/info/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ dependencies {
implementation(libs.coil.compose)
implementation(libs.bundles.koin)
implementation(libs.timber)
implementation(libs.immutableCollections)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.collections.immutable.persistentListOf
import org.koin.androidx.compose.koinViewModel
import org.koin.core.parameter.parametersOf
import ru.stersh.youamp.core.ui.Artwork
Expand Down Expand Up @@ -315,7 +316,7 @@ private fun AlbumSongItemPreview() {
@Preview(showBackground = true)
@Composable
private fun AlbumInfoScreenPreview() {
val songs = listOf(
val songs = persistentListOf(
AlbumSongUi(
id = "1",
track = 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
package ru.stersh.youamp.feature.album.ui

import androidx.compose.runtime.Immutable
import kotlinx.collections.immutable.ImmutableList

@Immutable
internal data class AlbumInfoStateUi(
val progress: Boolean = true,
val content: AlbumInfoUi? = null,
val error: Boolean = false
)

@Immutable
internal data class AlbumInfoUi(
val artworkUrl: String?,
val title: String,
val artist: String,
val year: String?,
val isFavorite: Boolean,
val songs: List<AlbumSongUi>
val songs: ImmutableList<AlbumSongUi>
)

@Immutable
internal data class AlbumSongUi(
val id: String,
val title: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ru.stersh.youamp.feature.album.ui

import kotlinx.collections.immutable.toImmutableList
import ru.stersh.youamp.feature.album.domain.AlbumInfo
import ru.stersh.youamp.feature.album.domain.AlbumSong

Expand All @@ -10,7 +11,9 @@ internal fun AlbumInfo.toUi(): AlbumInfoUi {
year = year,
artworkUrl = artworkUrl,
isFavorite = isFavorite,
songs = songs.map { it.toUi() }
songs = songs
.map { it.toUi() }
.toImmutableList()
)
}

Expand Down
1 change: 1 addition & 0 deletions feature/album/list/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ dependencies {
implementation(libs.coil.compose)
implementation(libs.bundles.koin)
implementation(libs.timber)
implementation(libs.immutableCollections)
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.collections.immutable.persistentListOf
import org.koin.androidx.compose.koinViewModel
import ru.stersh.youamp.core.ui.AlbumItem
import ru.stersh.youamp.core.ui.BackNavigationButton
Expand Down Expand Up @@ -171,7 +172,7 @@ private fun Progress() {
@Preview
private fun AlbumsScreenPreview() {
YouampPlayerTheme {
val items = listOf(
val items = persistentListOf(
AlbumUi(
id = "1",
title = "Test",
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ru.stersh.youamp.feature.albums.ui

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
Expand Down Expand Up @@ -42,7 +43,7 @@ internal class AlbumsViewModel(
progress = true,
isRefreshing = false,
error = false,
items = emptyList()
items = persistentListOf()
)
}
paginator.restart()
Expand Down Expand Up @@ -79,7 +80,7 @@ internal class AlbumsViewModel(
progress = false,
isRefreshing = false,
error = true,
items = emptyList()
items = persistentListOf()
)
}
}
Expand All @@ -98,7 +99,7 @@ internal class AlbumsViewModel(
progress = true,
isRefreshing = false,
error = false,
items = emptyList()
items = persistentListOf()
)
}
paginator.restart()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package ru.stersh.youamp.feature.albums.ui

import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList
import ru.stersh.youamp.feature.albums.domain.Album

internal fun List<Album>.toUi(): List<AlbumUi> = map { it.toUi() }
internal fun List<Album>.toUi(): ImmutableList<AlbumUi> {
return map { it.toUi() }.toPersistentList()
}

internal fun Album.toUi(): AlbumUi {
return AlbumUi(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ru.stersh.youamp.feature.albums.ui

import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf

internal data class AlbumsStateUi(
val progress: Boolean = true,
val isRefreshing: Boolean = false,
val error: Boolean = false,
val items: ImmutableList<AlbumUi> = persistentListOf()
)

internal data class AlbumUi(
val id: String,
val title: String,
val artist: String?,
val artworkUrl: String?
)
1 change: 1 addition & 0 deletions feature/artist/favorites/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ dependencies {
implementation(libs.coil.compose)
implementation(libs.bundles.koin)
implementation(libs.timber)
implementation(libs.immutableCollections)
}
Loading
Loading