Skip to content

Commit

Permalink
Merge pull request #122 from VictorKabata/fix-search-functionality-re…
Browse files Browse the repository at this point in the history
…vamp

Search functionality revamp
  • Loading branch information
VictorKabata authored Aug 26, 2024
2 parents f1a9ce6 + b4d8fb8 commit c0696a1
Show file tree
Hide file tree
Showing 15 changed files with 262 additions and 202 deletions.
Binary file modified notflix.preferences_pb
Binary file not shown.
2 changes: 2 additions & 0 deletions shared/src/commonMain/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
<string name="back">Back</string>
<string name="close_search">Close Search</string>

<string name="search_movie">Search Movie</string>

<string-array name="themes">
<item>Light theme</item>
<item>Dark theme</item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,30 +68,4 @@ class MoviesRepositoryImpl constructor(
}
)
}

/*override suspend fun getMovies(category: String): Flow<List<Movie>> {
val cachedResponse = moviesDao.getMoviesByCategory(category = category)
.map { it.map { movieEntity -> movieEntity.toDomain(category = category) } }
.onEach { movies ->
// if (movies.isEmpty()) fetchMovies(category = category)
}
return cachedResponse
}*/

override suspend fun searchMovie(
movieName: String,
page: Int
): Flow<ResultState<List<Movie>?>> {
return flowOf(
safeApiCall {
val response = httpClient.get(urlString = "search/movie") {
parameter("query", movieName)
parameter("page", page)
}.body<MovieResultsDto>()

response.movies?.map { it.toDomain() }
}
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.vickbt.shared.data.datasources

import com.vickbt.shared.data.mappers.toDomain
import com.vickbt.shared.data.network.models.MovieResultsDto
import com.vickbt.shared.data.network.utils.safeApiCall
import com.vickbt.shared.domain.models.Movie
import com.vickbt.shared.domain.repositories.SearchRepository
import com.vickbt.shared.utils.ResultState
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.request.get
import io.ktor.client.request.parameter
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf

class SearchRepositoryImpl(
private val httpClient: HttpClient
) : SearchRepository {

override suspend fun searchMovie(
movieName: String,
page: Int
): Flow<ResultState<List<Movie>?>> {
return flowOf(
safeApiCall {
val response = httpClient.get(urlString = "search/movie") {
parameter("query", movieName)
parameter("page", page)
}.body<MovieResultsDto>()

response.movies?.map { it.toDomain() }
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import com.vickbt.shared.data.cache.sqldelight.daos.FavoriteMovieDao
import com.vickbt.shared.data.datasources.FavoritesRepositoryImpl
import com.vickbt.shared.data.datasources.MovieDetailsRepositoryImpl
import com.vickbt.shared.data.datasources.MoviesRepositoryImpl
import com.vickbt.shared.data.datasources.SearchRepositoryImpl
import com.vickbt.shared.data.datasources.SettingsRepositoryImpl
import com.vickbt.shared.domain.repositories.FavoritesRepository
import com.vickbt.shared.domain.repositories.MovieDetailsRepository
import com.vickbt.shared.domain.repositories.MoviesRepository
import com.vickbt.shared.domain.repositories.SearchRepository
import com.vickbt.shared.domain.repositories.SettingsRepository
import com.vickbt.shared.domain.utils.Constants.BASE_URL
import com.vickbt.shared.domain.utils.Constants.URL_PATH
import com.vickbt.shared.ui.screens.details.DetailsViewModel
import com.vickbt.shared.ui.screens.favorites.FavoritesViewModel
import com.vickbt.shared.ui.screens.home.HomeViewModel
import com.vickbt.shared.ui.screens.main.MainViewModel
import com.vickbt.shared.ui.screens.search.SearchViewModel
import com.vickbt.shared.ui.screens.settings.SettingsViewModel
import io.github.aakira.napier.DebugAntilog
import io.github.aakira.napier.Napier
Expand Down Expand Up @@ -84,11 +87,13 @@ fun commonModule(enableNetworkLogs: Boolean) = module {
MovieDetailsRepositoryImpl(httpClient = get(), favoriteMovieDao = get())
}
single<FavoritesRepository> { FavoritesRepositoryImpl(favoriteMovieDao = get()) }
single<SearchRepository> { SearchRepositoryImpl(httpClient = get()) }
single<SettingsRepository> { SettingsRepositoryImpl(dataStore = get()) }

viewModelOf(::MainViewModel)
viewModelOf(::HomeViewModel)
viewModelOf(::DetailsViewModel)
viewModelOf(::SearchViewModel)
viewModelOf(::SettingsViewModel)
viewModelOf(::FavoritesViewModel)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,4 @@ interface MoviesRepository {

/** Fetch Upcoming movies from data source*/
suspend fun fetchUpcomingMovies(page: Int = STARTING_PAGE_INDEX): Flow<ResultState<List<Movie>?>>

/** Get movies based on category from cache*/
/*@Deprecated("Pending caching implementation")
suspend fun getMovies(category: String): Flow<List<Movie>>*/

// Search movie from network source
suspend fun searchMovie(
movieName: String,
page: Int = STARTING_PAGE_INDEX
): Flow<ResultState<List<Movie>?>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.vickbt.shared.domain.repositories

import com.vickbt.shared.domain.models.Movie
import com.vickbt.shared.domain.utils.Constants.STARTING_PAGE_INDEX
import com.vickbt.shared.utils.ResultState
import kotlinx.coroutines.flow.Flow

interface SearchRepository {

// Search movie from network source
suspend fun searchMovie(
movieName: String,
page: Int = STARTING_PAGE_INDEX
): Flow<ResultState<List<Movie>?>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.navigation.navArgument
import com.vickbt.shared.ui.screens.details.DetailsScreen
import com.vickbt.shared.ui.screens.favorites.FavoritesScreen
import com.vickbt.shared.ui.screens.home.HomeScreen
import com.vickbt.shared.ui.screens.search.SearchScreen
import com.vickbt.shared.ui.screens.settings.SettingsScreen
import com.vickbt.shared.utils.WindowSize
import io.github.aakira.napier.Napier
Expand All @@ -18,23 +19,31 @@ import io.github.aakira.napier.Napier
fun Navigation(
navHostController: NavHostController,
windowSize: WindowSize,
paddingValues: PaddingValues = PaddingValues()
mainPaddingValues: PaddingValues = PaddingValues()
) {
NavHost(navController = navHostController, startDestination = NavigationItem.Home.route) {
composable(route = NavigationItem.Home.route) {
HomeScreen(
navigator = navHostController,
windowSize = windowSize,
paddingValues = paddingValues
mainPaddingValues = mainPaddingValues
)
}

composable(route = NavigationItem.Favorites.route) {
FavoritesScreen(navigator = navHostController)
FavoritesScreen(navigator = navHostController, mainPaddingValues = mainPaddingValues)
}

composable(route = NavigationItem.Search.route) {
SearchScreen(
windowSize = windowSize,
navigator = navHostController,
mainPaddingValues = mainPaddingValues
)
}

composable(route = NavigationItem.Settings.route) {
SettingsScreen()
SettingsScreen(mainPaddingValues = mainPaddingValues)
}

composable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package com.vickbt.shared.ui.screens.favorites

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
Expand All @@ -26,17 +27,19 @@ import org.koin.core.annotation.KoinExperimentalAPI
@Composable
fun FavoritesScreen(
navigator: NavHostController,
viewModel: FavoritesViewModel = koinViewModel<FavoritesViewModel>()
viewModel: FavoritesViewModel = koinViewModel<FavoritesViewModel>(),
mainPaddingValues: PaddingValues
) {
val favoriteMovies = viewModel.favoriteMoviesState.collectAsState().value

Scaffold(
modifier = Modifier.padding(mainPaddingValues),
topBar = { AppBar(stringResource(Res.string.title_favorites)) }
) { paddingValues ->
Box(modifier = Modifier.fillMaxSize().padding(paddingValues)) {
LazyColumn(
modifier = Modifier.fillMaxSize()
.padding(bottom = 90.dp, start = 16.dp, end = 16.dp)
.padding(horizontal = 16.dp)
) {
items(items = favoriteMovies.favoriteMovies ?: emptyList()) { favoriteMovie ->
MovieCardDescription(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.vickbt.shared.ui.screens.home

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
Expand All @@ -18,48 +17,30 @@ import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.rounded.Close
import androidx.compose.material.icons.rounded.Search
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SearchBar
import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import com.vickbt.shared.resources.Res
import com.vickbt.shared.resources.popular_movies
import com.vickbt.shared.resources.trending_movies
import com.vickbt.shared.resources.upcoming_movies
import com.vickbt.shared.ui.components.MovieCardLandscape
import com.vickbt.shared.ui.components.MovieCardPager
import com.vickbt.shared.ui.components.MovieCardPagerIndicator
import com.vickbt.shared.ui.components.MovieCardPortraitCompact
import com.vickbt.shared.ui.components.SectionSeparator
import com.vickbt.shared.ui.screens.search.SearchScreen
import com.vickbt.shared.ui.components.appbars.AppBar
import com.vickbt.shared.ui.theme.DarkPrimaryColor
import com.vickbt.shared.utils.WindowSize
import com.vickbt.shared.resources.Res
import com.vickbt.shared.resources.back
import com.vickbt.shared.resources.close_search
import com.vickbt.shared.resources.popular_movies
import com.vickbt.shared.resources.title_search
import com.vickbt.shared.resources.trending_movies
import com.vickbt.shared.resources.upcoming_movies
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel

Expand All @@ -69,87 +50,18 @@ fun HomeScreen(
navigator: NavHostController,
windowSize: WindowSize = WindowSize.COMPACT,
viewModel: HomeViewModel = koinViewModel<HomeViewModel>(),
paddingValues: PaddingValues
mainPaddingValues: PaddingValues
) {
val scrollState = rememberScrollState()

val homeUiState = viewModel.homeUiState.collectAsState().value
val searchUiState = viewModel.searchUiState.collectAsState().value

var searchQuery by remember { mutableStateOf("") }
var activeState by remember { mutableStateOf(false) }

Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(
space = 6.dp,
alignment = Alignment.CenterVertically
)
) {
//region Search
SearchBar(
modifier = Modifier.background(
MaterialTheme.colorScheme.surface
).also {
if (activeState) it.fillMaxWidth() else it.fillMaxWidth(.85f)
},
query = searchQuery,
onQueryChange = { searchQuery = it },
onSearch = { viewModel.searchMovie(movieName = it) },
active = activeState,
onActiveChange = { activeState = it },
placeholder = {
Text(
text = stringResource(Res.string.title_search),
fontSize = 18.sp,
style = MaterialTheme.typography.titleMedium,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
textAlign = TextAlign.Start
)
},
leadingIcon = {
if (activeState) {
IconButton(onClick = {
activeState = false
searchQuery = ""
}) {
Icon(
imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
contentDescription = stringResource(Res.string.back)
)
}
} else {
Icon(imageVector = Icons.Rounded.Search, contentDescription = "Search")
}
},
trailingIcon = {
if (activeState) {
IconButton(onClick = {
if (searchQuery.isNotEmpty()) searchQuery = "" else activeState = false
}) {
Icon(
imageVector = Icons.Rounded.Close,
contentDescription = stringResource(Res.string.close_search)
)
}
} else {
null
}
},
colors = SearchBarDefaults.colors(
dividerColor = Color.LightGray,
// inputFieldColors = TextFieldDefaults.colors()
)
) {
SearchScreen(
navigator = navigator,
searchUiState = searchUiState,
windowSize = windowSize
)
}
//endregion
Scaffold(
modifier = Modifier
.fillMaxSize()
.padding(mainPaddingValues),
topBar = { AppBar("Home") }
) { paddingValues ->

// region Home section
Box(
Expand Down Expand Up @@ -284,11 +196,11 @@ fun HomeScreen(
}
}
}
//endregion
}
//endregion
}
}
// endregion
}
// endregion
}
}
Loading

0 comments on commit c0696a1

Please sign in to comment.