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

ISSUE-74 - Search screen #87

Merged
merged 10 commits into from
Oct 12, 2023
1 change: 1 addition & 0 deletions src/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ dependencies {
api(project(":feature_movies"))
api(project(":feature_details"))
api(project(":feature_wishlist"))
api(project(":feature_search"))

implementation(libs.appcompat)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.gabrielbmoro.moviedb.core.ui.parcelableOf
import com.gabrielbmoro.moviedb.details.ui.screens.details.DetailsScreen
import com.gabrielbmoro.moviedb.movies.ui.screens.movies.MovieScreen
import com.gabrielbmoro.moviedb.repository.model.Movie
import com.gabrielbmoro.moviedb.search.ui.screens.search.SearchScreen
import com.gabrielbmoro.moviedb.wishlist.ui.screens.wishlist.WishlistScreen

@Composable
Expand All @@ -21,6 +22,10 @@ fun MovieDBNavHost(
)
}

val onBack: (() -> Unit) = {
navController.navigateUp()
}

val bottomBar: @Composable (() -> Unit) = {
MovieBottomNavigationBar(
navController = navController,
Expand All @@ -38,7 +43,10 @@ fun MovieDBNavHost(
) {
MovieScreen(
bottomBar = bottomBar,
navigateToDetailsScreen = navigateToDetailsScreen
navigateToDetailsScreen = navigateToDetailsScreen,
navigateToSearchScreen = {
navController.navigate(ScreenRoutesBuilder.SEARCH_ROUTE)
}
)
}

Expand All @@ -49,6 +57,15 @@ fun MovieDBNavHost(
)
}

composable(
route = ScreenRoutesBuilder.SEARCH_ROUTE
) {
SearchScreen(
navigateToDetailsScreen = navigateToDetailsScreen,
onBackEvent = onBack
)
}

composable(
route = "${ScreenRoutesBuilder.DETAILED_MOVIE_ROUTE}/{${ScreenRoutesBuilder.DETAILED_MOVIE_ARGUMENT_KEY}}",
arguments = listOf(
Expand All @@ -63,9 +80,7 @@ fun MovieDBNavHost(
) ?: throw IllegalArgumentException("Type should be movie")

DetailsScreen(
onBackEvent = {
navController.navigateUp()
},
onBackEvent = onBack,
movie = movie
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ object ScreenRoutesBuilder {
private const val HOME_SCREEN_ROUTE = "home"
const val WISHLIST_ROUTE = "$HOME_SCREEN_ROUTE/favoriteMovies"
const val MOVIES_ROUTE = "$HOME_SCREEN_ROUTE/moviesRoute"
const val SEARCH_ROUTE = "$HOME_SCREEN_ROUTE/search"

fun detailedMovieRoute(movie: Movie): String {
val json = Uri.encode(Gson().toJson(movie))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class AppToolbarTest {

// act
composeTestRule.setContent {
AppToolbar(
AppToolbarTitle(
title = title
)
}
Expand All @@ -37,7 +37,7 @@ class AppToolbarTest {

// act
composeTestRule.setContent {
AppToolbar(
AppToolbarTitle(
title = "any title",
backEvent = backEvent
)
Expand All @@ -56,7 +56,7 @@ class AppToolbarTest {

// act
composeTestRule.setContent {
AppToolbar(
AppToolbarTitle(
title = "any title",
backEvent = backEvent
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.gabrielbmoro.moviedb.core.ui.widgets

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
Expand All @@ -10,27 +11,73 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import com.gabrielbmoro.moviedb.core.R
import com.gabrielbmoro.moviedb.core.ui.theme.MovieDBAppTheme
import com.gabrielbmoro.moviedb.core.ui.theme.ThemePreviews

@Composable
private fun BackNavigationIcon(event: (() -> Unit), modifier: Modifier = Modifier) {
IconButton(onClick = event, modifier = modifier) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = stringResource(id = R.string.back)
)
}
}

@Composable
private fun SearchNavigationIcon(event: () -> Unit, modifier: Modifier = Modifier) {
IconButton(onClick = event, modifier = modifier) {
Icon(
imageVector = Icons.Filled.Search,
contentDescription = stringResource(id = R.string.search)
)
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppToolbar(
title: String,
backEvent: (() -> Unit)? = null
fun CustomAppToolbar(
title: @Composable () -> Unit,
backEvent: (() -> Unit)? = null,
searchEvent: (() -> Unit)? = null
) {
val navigationIcon: @Composable (() -> Unit) = backEvent?.let {
val backNavigationIcon: @Composable (() -> Unit) = backEvent?.let {
{
IconButton(onClick = backEvent) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = stringResource(id = R.string.back)
)
BackNavigationIcon(it)
}
} ?: { }

TopAppBar(
title = {
title()
},
navigationIcon = backNavigationIcon,
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer
),
actions = {
searchEvent?.let { searchEvent ->
SearchNavigationIcon(event = searchEvent)
}
}
)
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppToolbarTitle(
title: String,
backEvent: (() -> Unit)? = null,
searchEvent: (() -> Unit)? = null
) {
val backNavigationIcon: @Composable (() -> Unit) = backEvent?.let {
{
BackNavigationIcon(it)
}
} ?: { }

TopAppBar(
Expand All @@ -41,17 +88,22 @@ fun AppToolbar(
overflow = TextOverflow.Ellipsis
)
},
navigationIcon = navigationIcon,
navigationIcon = backNavigationIcon,
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer
)
),
actions = {
searchEvent?.let { searchEvent ->
SearchNavigationIcon(event = searchEvent)
}
}
)
}

@ThemePreviews
@Composable
fun AppToolbarPreview() {
MovieDBAppTheme {
AppToolbar("Jumangi")
AppToolbarTitle("Jumangi")
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.gabrielbmoro.moviedb.wishlist.ui.widgets
package com.gabrielbmoro.moviedb.core.ui.widgets

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
Expand All @@ -17,7 +17,6 @@ import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.gabrielbmoro.moviedb.core.R
import com.gabrielbmoro.moviedb.core.ui.widgets.MovieImage

@Composable
fun MovieCard(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.gabrielbmoro.moviedb.wishlist.ui.widgets
package com.gabrielbmoro.moviedb.core.ui.widgets

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
Expand All @@ -16,7 +16,6 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.gabrielbmoro.moviedb.core.ui.widgets.FiveStars

@Composable
fun MovieCardInformation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ fun ScreenScaffold(
showTopBar: Boolean,
appBarTitle: String,
modifier: Modifier = Modifier,
searchEvent: (() -> Unit)? = null,
bottomBar: @Composable () -> Unit,
screenContent: @Composable BoxScope.() -> Unit
) {
Expand All @@ -30,9 +31,10 @@ fun ScreenScaffold(
),
exit = shrinkVertically()
) {
AppToolbar(
AppToolbarTitle(
title = appBarTitle,
backEvent = null
backEvent = null,
searchEvent = searchEvent
)
}
},
Expand Down
1 change: 1 addition & 0 deletions src/core/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="back">Back</string>
<string name="search">Search</string>
<string name="empty_view_title">No movie here</string>
<string name="alt_sad_emoji">Sad emoji</string>
<string name="poster">Poster</string>
Expand Down
16 changes: 0 additions & 16 deletions src/core_testing/build.gradle.kts

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ interface MoviesRepository {
fun getVideoStreams(movieId: Long): Flow<List<VideoStream>>

fun getMovieDetail(movieId: Long): Flow<MovieDetail>

fun searchMovieBy(query: String): Flow<List<Movie>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ class MoviesRepositoryImpl @Inject constructor(
}
}

override fun searchMovieBy(query: String): Flow<List<Movie>> = flow {
val result = api.searchMovieBy(query = query)
val movies = result.results?.map { movieMapper.mapResponse(it) } ?: emptyList()
emit(movies)
}

companion object {
private const val PAGE_SIZE = 20
private const val MAX_SIZE = 500
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,14 @@ interface ApiRepository {
suspend fun getMovieDetails(
@Path("movie_id") movieId: Long
): MovieDetailResponse

@GET("search/movie")
suspend fun searchMovieBy(
@Query("query")
query: String,
@Query("include_adult")
includeAdult: Boolean = false,
@Query("language")
language: String = "en-US"
): PageResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.gabrielbmoro.moviedb.core.ui.widgets.AppToolbar
import com.gabrielbmoro.moviedb.core.ui.widgets.AppToolbarTitle
import com.gabrielbmoro.moviedb.core.ui.widgets.BubbleLoader
import com.gabrielbmoro.moviedb.core.ui.widgets.MovieImage
import com.gabrielbmoro.moviedb.details.ui.screens.fullscreen.FullScreenActivity
Expand Down Expand Up @@ -90,7 +90,7 @@ private fun DetailsScreenMain(
enter = fadeIn(),
exit = fadeOut()
) {
AppToolbar(
AppToolbarTitle(
title = uiState.movieTitle,
backEvent = onBackEvent
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.gabrielbmoro.moviedb.repository.model.Movie
fun MovieScreen(
bottomBar: @Composable (() -> Unit),
navigateToDetailsScreen: ((Movie) -> Unit),
navigateToSearchScreen: (() -> Unit),
viewModel: MoviesViewModel = hiltViewModel()
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
Expand All @@ -40,6 +41,7 @@ fun MovieScreen(
ScreenScaffold(
showTopBar = showTopBar,
appBarTitle = stringResource(id = R.string.movies),
searchEvent = navigateToSearchScreen,
bottomBar = bottomBar
) {
LazyColumn(
Expand Down
File renamed without changes.
Loading