Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,54 @@ class FilmPosterTest {

assertTrue(clicked)
}

@Test
fun film_poster_hides_results_chip_when_count_is_zero() {
val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
setImageLoader(
FakeImageLoaderEngine
.Builder()
.default(bitmap.asImage())
.build(),
)

composeTestRule.setContent {
FilmPoster(
imageUrl = "https://example.com/poster.jpg",
title = "Test Film",
releaseYear = "2020",
onClick = {},
onRerollClick = {},
numberOfResults = 0,
)
}

composeTestRule.waitForIdle()
composeTestRule.onNodeWithTag("results-count-chip").assertDoesNotExist()
}

@Test
fun film_poster_shows_results_chip_when_count_is_greater_than_zero() {
val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
setImageLoader(
FakeImageLoaderEngine
.Builder()
.default(bitmap.asImage())
.build(),
)

composeTestRule.setContent {
FilmPoster(
imageUrl = "https://example.com/poster.jpg",
title = "Test Film",
releaseYear = "2020",
onClick = {},
onRerollClick = {},
numberOfResults = 42,
)
}

composeTestRule.waitForIdle()
composeTestRule.onNodeWithTag("results-count-chip").assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ fun RandomFilmScreenRoot(
val filmSearchMode by stateFlow.map { it.filmSearchMode }.collectAsStateWithLifecycle(initialValue = FilmSearchMode.INTERSECTION)
val selectedGenres by stateFlow.map { it.selectedGenres }.collectAsStateWithLifecycle(initialValue = emptySet())
val showGenreBottomSheet by stateFlow.map { it.showGenreBottomSheet }.collectAsStateWithLifecycle(initialValue = false)
val numberOfResults by stateFlow.map { it.numberOfResults }.collectAsStateWithLifecycle(initialValue = 0)

val usernameState = remember { TextFieldState(userName) }

Expand Down Expand Up @@ -99,6 +100,7 @@ fun RandomFilmScreenRoot(
filmSearchMode = filmSearchMode,
selectedGenres = selectedGenres,
showGenreBottomSheet = showGenreBottomSheet,
numberOfResults = numberOfResults,
userNameList = viewModel.userNameList,
onAction = onAction,
)
Expand All @@ -114,6 +116,7 @@ fun RandomFilmScreen(
filmSearchMode: FilmSearchMode = FilmSearchMode.INTERSECTION,
selectedGenres: Set<FilmGenre> = emptySet(),
showGenreBottomSheet: Boolean = false,
numberOfResults: Int = 0,
userNameList: StateFlow<List<UserName>> = MutableStateFlow(emptyList()),
onAction: (RandomFilmAction) -> Unit = {},
) {
Expand Down Expand Up @@ -160,7 +163,7 @@ fun RandomFilmScreen(
FilmErrorView(it)
}
resultFilm?.takeIf { !isLoading }?.let {
FilmDisplay(it, onAction)
FilmDisplay(it, onAction, numberOfResults)
} ?: LoadingOrPrompt(isLoading)

if (resultError == null && resultFilm == null && !isLoading) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.nacchofer31.randomboxd.random_film.presentation.viewmodel.RandomFilmA
internal fun FilmDisplay(
film: Film,
onAction: (RandomFilmAction) -> Unit,
numberOfResults: Int = 0,
) = Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(vertical = 20.dp).testTag("test-film-display"),
Expand All @@ -28,5 +29,6 @@ internal fun FilmDisplay(
onRerollClick = {
onAction(RandomFilmAction.OnRerollClicked)
},
numberOfResults = numberOfResults,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ fun FilmPoster(
releaseYear: String,
onClick: () -> Unit,
onRerollClick: () -> Unit,
numberOfResults: Int = 0,
) {
var imageLoadResult by remember {
mutableStateOf<Result<Painter>?>(null)
Expand Down Expand Up @@ -116,38 +117,53 @@ fun FilmPoster(
modifier =
Modifier
.fillMaxWidth()
.aspectRatio(280f / 360f)
.clip(RoundedCornerShape(12.dp))
.clickable { onClick() },
.aspectRatio(280f / 360f),
) {
Image(
painter = painter,
contentDescription = "film_image",
modifier = Modifier.fillMaxSize(),
contentScale =
if (result.isSuccess) {
ContentScale.Crop
} else {
ContentScale.Fit
},
)
Box(
modifier =
Modifier
.padding(8.dp)
.size(28.dp)
.background(
color = Color.Black.copy(alpha = 0.7f),
shape = RoundedCornerShape(14.dp),
).align(Alignment.TopStart)
.fillMaxSize()
.clip(RoundedCornerShape(12.dp))
.clickable { onClick() },
contentAlignment = Alignment.Center,
) {
Icon(
imageVector = Icons.Outlined.Info,
contentDescription = "info_icon",
tint = RandomBoxdColors.White,
modifier = Modifier.size(16.dp),
Image(
painter = painter,
contentDescription = "film_image",
modifier = Modifier.fillMaxSize(),
contentScale =
if (result.isSuccess) {
ContentScale.Crop
} else {
ContentScale.Fit
},
)
Box(
modifier =
Modifier
.padding(8.dp)
.size(28.dp)
.background(
color = Color.Black.copy(alpha = 0.7f),
shape = RoundedCornerShape(14.dp),
).align(Alignment.TopStart)
.clickable { onClick() },
contentAlignment = Alignment.Center,
) {
Icon(
imageVector = Icons.Outlined.Info,
contentDescription = "info_icon",
tint = RandomBoxdColors.White,
modifier = Modifier.size(16.dp),
)
}
}
if (numberOfResults > 0) {
ResultsCountChip(
count = numberOfResults,
modifier =
Modifier
.padding(8.dp)
.align(Alignment.TopEnd),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.nacchofer31.randomboxd.random_film.presentation.components

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Movie
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.nacchofer31.randomboxd.core.presentation.RandomBoxdColors

@Composable
fun ResultsCountChip(
count: Int,
modifier: Modifier = Modifier,
) {
Row(
modifier =
modifier
.height(28.dp)
.background(
color = RandomBoxdColors.GreenAccent,
shape = RoundedCornerShape(14.dp),
).padding(horizontal = 10.dp)
.testTag("results-count-chip"),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp),
) {
Icon(
imageVector = Icons.Outlined.Movie,
contentDescription = "results_count_icon",
tint = RandomBoxdColors.BackgroundDarkColor,
modifier = Modifier.size(14.dp),
)
Text(
text = count.toString(),
fontSize = 12.sp,
fontWeight = FontWeight.SemiBold,
color = RandomBoxdColors.BackgroundDarkColor,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ data class RandomFilmState(
val filmSearchMode: FilmSearchMode = FilmSearchMode.INTERSECTION,
val selectedGenres: Set<FilmGenre> = emptySet(),
val showGenreBottomSheet: Boolean = false,
val numberOfResults: Int = 0,
)
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class RandomFilmViewModel(
emit(result)
}.onStart {
internalState.update { state ->
state.copy(isLoading = true, resultError = null, resultFilm = null)
state.copy(isLoading = true, resultError = null, resultFilm = null, numberOfResults = 0)
}
}.flowOn(dispatchers.main)
}.onEach { result ->
Expand All @@ -99,6 +99,7 @@ class RandomFilmViewModel(
isLoading = false,
resultFilm = filmResult.data,
resultError = null,
numberOfResults = cachedResultFilms.size,
)
}

Expand All @@ -107,6 +108,7 @@ class RandomFilmViewModel(
isLoading = false,
resultFilm = null,
resultError = filmResult.error,
numberOfResults = 0,
)
}
}
Expand All @@ -117,6 +119,7 @@ class RandomFilmViewModel(
isLoading = false,
resultFilm = null,
resultError = result.error,
numberOfResults = 0,
)
}
}
Expand Down Expand Up @@ -249,8 +252,8 @@ class RandomFilmViewModel(
)
internalState.update {
when (filmResult) {
is ResultData.Success -> it.copy(isLoading = false, resultFilm = filmResult.data, resultError = null)
is ResultData.Error -> it.copy(isLoading = false, resultFilm = null, resultError = filmResult.error)
is ResultData.Success -> it.copy(isLoading = false, resultFilm = filmResult.data, resultError = null, numberOfResults = cachedResultFilms.size)
is ResultData.Error -> it.copy(isLoading = false, resultFilm = null, resultError = filmResult.error, numberOfResults = 0)
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions randomboxd.pen
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,44 @@
"fill": "$text-primary"
}
]
},
{
"type": "frame",
"id": "tUtrd",
"x": 131,
"y": 8,
"name": "resultsChip",
"height": 28,
"fill": "$accent-green",
"cornerRadius": 14,
"gap": 4,
"padding": [
0,
10
],
"alignItems": "center",
"children": [
{
"type": "icon",
"id": "JScqq",
"name": "filmIcon",
"width": 14,
"height": 14,
"icon": "film",
"library": "lucide",
"fill": "#14181C"
},
{
"type": "text",
"id": "SBmEz",
"name": "resultsCount",
"fill": "#14181C",
"content": "247",
"fontFamily": "Inter",
"fontSize": 12,
"fontWeight": "600"
}
]
}
]
},
Expand Down
Loading