From 71727d3c38b3332e93e6e73c06f762c70a077117 Mon Sep 17 00:00:00 2001 From: Florian Burgener <florian.brgnr@gmail.com> Date: Tue, 2 Jan 2024 00:24:00 +0100 Subject: [PATCH] Add view models 1 --- .editorconfig | 13 + .../Components/LibraryComponent.kt | 136 --- .../Components/MovieCardComponent.kt | 236 ----- .../Components/SearchMovieComponent.kt | 131 --- .../com/example/moviestudio/MainActivity.kt | 9 +- .../components}/BottomNavItem.kt | 60 +- .../components}/BottomNavigation.kt | 127 ++- .../components/CommonComponents.kt} | 279 ++--- .../ui/components/MovieCardComponent.kt | 112 ++ .../screens/LibraryScreen.kt} | 955 +++++++++--------- .../ui/screens/SearchMovieScreen.kt | 322 ++++++ .../screens/SettingsScreen.kt} | 166 +-- .../viewmodels/LibraryViewModel.kt | 99 ++ .../viewmodels/SearchMovieViewModel.kt | 40 + .../viewmodels/SettingsViewModel.kt | 9 + .../viewmodels/ShowMovieViewModel.kt | 35 + 16 files changed, 1454 insertions(+), 1275 deletions(-) create mode 100644 .editorconfig delete mode 100644 src/app/src/main/java/com/example/moviestudio/Components/LibraryComponent.kt delete mode 100644 src/app/src/main/java/com/example/moviestudio/Components/MovieCardComponent.kt delete mode 100644 src/app/src/main/java/com/example/moviestudio/Components/SearchMovieComponent.kt rename src/app/src/main/java/com/example/moviestudio/{Components => ui/components}/BottomNavItem.kt (81%) rename src/app/src/main/java/com/example/moviestudio/{Components => ui/components}/BottomNavigation.kt (94%) rename src/app/src/main/java/com/example/moviestudio/{Components/Components.kt => ui/components/CommonComponents.kt} (78%) create mode 100644 src/app/src/main/java/com/example/moviestudio/ui/components/MovieCardComponent.kt rename src/app/src/main/java/com/example/moviestudio/{Components/PopupComponent.kt => ui/screens/LibraryScreen.kt} (63%) create mode 100644 src/app/src/main/java/com/example/moviestudio/ui/screens/SearchMovieScreen.kt rename src/app/src/main/java/com/example/moviestudio/{Components/SettingsComponent.kt => ui/screens/SettingsScreen.kt} (86%) create mode 100644 src/app/src/main/java/com/example/moviestudio/viewmodels/LibraryViewModel.kt create mode 100644 src/app/src/main/java/com/example/moviestudio/viewmodels/SearchMovieViewModel.kt create mode 100644 src/app/src/main/java/com/example/moviestudio/viewmodels/SettingsViewModel.kt create mode 100644 src/app/src/main/java/com/example/moviestudio/viewmodels/ShowMovieViewModel.kt diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3edb07c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + diff --git a/src/app/src/main/java/com/example/moviestudio/Components/LibraryComponent.kt b/src/app/src/main/java/com/example/moviestudio/Components/LibraryComponent.kt deleted file mode 100644 index e0eb21a..0000000 --- a/src/app/src/main/java/com/example/moviestudio/Components/LibraryComponent.kt +++ /dev/null @@ -1,136 +0,0 @@ -package com.example.moviestudio.Components - -import android.annotation.SuppressLint -import android.util.Log -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults -import androidx.compose.runtime.Composable -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.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.navigation.NavController -import com.example.moviestudio.Movie -import com.example.moviestudio.R -import com.example.moviestudio.UserRating -import com.example.moviestudio.ui.theme.dark -import com.example.moviestudio.ui.theme.main - -@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun Library(navController: NavController) { - var isPopupVisible by remember { mutableStateOf(false) } - val appName = stringResource(id = R.string.app_name) - val pageName = stringResource(id = R.string.app_library) - - var searchQuery by remember { mutableStateOf("") } - - var movieTitle by remember { mutableStateOf("Inception") } - var movieDescription by remember { mutableStateOf("Dom Cobb est un voleur expérimenté dans l'art périlleux de `l'extraction' : sa spécialité consiste à s'approprier les secrets les plus précieux d'un individu, enfouis au plus profond de son subconscient, pendant qu'il rêve et que son esprit est particulièrement vulnérable. Très recherché pour ses talents dans l'univers trouble de l'espionnage industriel, Cobb est aussi devenu un fugitif traqué dans le monde entier. Cependant, une ultime mission pourrait lui permettre de retrouver sa vie d'avant.") } - var moviePoster = "./poster" //painterResource(id = R.drawable.ic_launcher_background) - var movieReleaseDate = "10 juillet 2012" - var movieActors = "Leonardo Di Caprio, Marion Cotillard, Cilian Murphy, ..." - var movieGenres = "Thriller, Action, Intrigue, Amour, Science-fiction, ..." - - var movie = Movie( - id = 0, - name = movieTitle, - description = movieDescription, - poster = moviePoster, - releaseDate = movieReleaseDate, - actors = movieActors, - genres = movieGenres - ) - - var userRating = UserRating( - id = 0, - comment = "", - rating = 3, - movieId = movie.id - ) - - Scaffold( - modifier = Modifier, - topBar = { - if (!isPopupVisible) { - TopAppBar(colors = TopAppBarDefaults.smallTopAppBarColors( - containerColor = main, - titleContentColor = Color.White, - ), title = { - Column { - Text(text = appName, fontSize = 24.sp) - Text(text = pageName, fontSize = 16.sp) - } - } - ) - } - }, - content = { - // Content with a Column containing search components and LazyColumn - Column( - modifier = Modifier - .background(dark) - .fillMaxSize() - .padding(4.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - if (!isPopupVisible) { - SearchBarAndFilters( - searchQuery = searchQuery, - onSearchQueryChange = { searchQuery = it }, - onDateSelected = { selectedDate -> Log.i("LIBRARY", "Selected Date: $selectedDate") }, - onActorSelected = { selectedActor -> Log.i("LIBRARY", "Selected Actor: $selectedActor") }, - onGenreSelected = { selectedGenre -> Log.i("LIBRARY","Selected Genre: $selectedGenre") } - ) - } - - // LazyColumn - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .weight(1f) - ) { - items((0..5).toList()) { _ -> - MovieCardLibrary( - movie = movie, - onKnowMoreClick = { isPopupVisible = true }, - onDeleteClick = { Log.i("LIBRARY", "Delete movie from library") } - ) - } - } - - - ShowMovie( - isPopupVisible = isPopupVisible, - onCloseClick = { isPopupVisible = false }, - movie = movie, - userRating = userRating - ) - Spacer(modifier = Modifier.height(55.dp)) - } - }, - bottomBar = { - BottomNavigation(navController = navController) - } - ) -} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/moviestudio/Components/MovieCardComponent.kt b/src/app/src/main/java/com/example/moviestudio/Components/MovieCardComponent.kt deleted file mode 100644 index 5216c25..0000000 --- a/src/app/src/main/java/com/example/moviestudio/Components/MovieCardComponent.kt +++ /dev/null @@ -1,236 +0,0 @@ -package com.example.moviestudio.Components - -import androidx.compose.foundation.Image -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.Divider -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.example.moviestudio.Movie -import com.example.moviestudio.R -import com.example.moviestudio.ui.theme.second - -@Composable -fun MovieCard( - movie: Movie, - onKnowMoreClick: () -> Unit, - modifier: Modifier = Modifier, - actionButton: (@Composable () -> Unit)? = null -) { - var poster = painterResource(id = R.drawable.ic_launcher_background) - Box( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - .then(modifier) - ) { - Row() { - Image( - painter = poster, - contentDescription = "Movie Poster", - modifier = Modifier - .height(220.dp) - .width(120.dp) - .clip(MaterialTheme.shapes.medium), - contentScale = ContentScale.Crop - ) - - // Movie details on the right - Column( - modifier = Modifier - .fillMaxWidth() - .padding(start = 16.dp) - ) { - Text( - text = movie.name, - fontSize = 20.sp, - fontWeight = FontWeight.Bold, - color = Color.White - ) - Text( - text = movie.description.take(120) + "...", - fontSize = 16.sp, - color = Color.White, - textAlign = TextAlign.Left - ) - - // Buttons - Row( - modifier = Modifier - .fillMaxWidth() - .padding(top = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(top = 10.dp) - ) { - Button( - onClick = onKnowMoreClick, - modifier = Modifier.fillMaxWidth(), - colors = ButtonDefaults.buttonColors(containerColor = second) - ) { - Text(text = stringResource(id = R.string.app_moreInformations)) - } - actionButton?.invoke() - } - } - } - } - } - Spacer(modifier = Modifier.height(2.dp)) - Divider( - color = Color.LightGray, - thickness = 0.01.dp, - modifier = Modifier - .fillMaxWidth() - .height(LocalDensity.current.density.dp) - ) -} - -@Composable -fun MovieCardLibrary( - movie: Movie, - onKnowMoreClick: () -> Unit, - onDeleteClick: () -> Unit -) { - var poster = painterResource(id = R.drawable.ic_launcher_background) - Box( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - ) { - // Movie poster on the left - Image( - painter = poster, - contentDescription = "Movie Poster", - modifier = Modifier - .height(220.dp) - .width(120.dp) - .clip(MaterialTheme.shapes.medium), - contentScale = ContentScale.Crop - ) - - // Movie details in the middle - Column( - modifier = Modifier - .fillMaxWidth() - .padding(start = 16.dp) - ) { - Text( - text = movie.name, - fontSize = 20.sp, - fontWeight = FontWeight.Bold, - color = Color.White - ) - Text( - text = movie.description.take(120) + "...", - fontSize = 16.sp, - color = Color.White, - textAlign = TextAlign.Left, - modifier = Modifier.padding(top = 6.dp) - ) - - // Buttons - Row( - modifier = Modifier - .fillMaxWidth() - .padding(top = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Column( - modifier = Modifier.fillMaxWidth() - ) { - Button( - onClick = onKnowMoreClick, - modifier = Modifier.fillMaxWidth(), - colors = ButtonDefaults.buttonColors(containerColor = second) - ) { - Text(text = "Plus d'informations") - } - } - } - } - } - - // Trash icon in the top-right corner - Icon( - painter = painterResource(id = R.drawable.baseline_delete_24), - contentDescription = "Delete", - modifier = Modifier - .padding(8.dp) - .size(24.dp) - .clickable { onDeleteClick() } - .align(Alignment.TopEnd), - tint = Color.White, - ) - } - - Spacer(modifier = Modifier.height(2.dp)) - Divider( - color = Color.LightGray, - thickness = 0.01.dp, - modifier = Modifier - .fillMaxWidth() - .height(LocalDensity.current.density.dp) - ) -} - -@Composable -fun MovieCardSearch( - movie: Movie, - onKnowMoreClick: () -> Unit, - onAddToLibraryClick: () -> Unit -) { - MovieCard( - movie = movie, - onKnowMoreClick = onKnowMoreClick, - actionButton = { - Button( - onClick = onAddToLibraryClick, - modifier = Modifier.fillMaxWidth(), - colors = ButtonDefaults.buttonColors(containerColor = second) - ) { - Text(text = stringResource(id = R.string.app_library)) - Icon( - imageVector = Icons.Default.Add, - contentDescription = null, - tint = Color.White - ) - } - } - ) -} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/moviestudio/Components/SearchMovieComponent.kt b/src/app/src/main/java/com/example/moviestudio/Components/SearchMovieComponent.kt deleted file mode 100644 index a0d5bf8..0000000 --- a/src/app/src/main/java/com/example/moviestudio/Components/SearchMovieComponent.kt +++ /dev/null @@ -1,131 +0,0 @@ -package com.example.moviestudio.Components - -import android.annotation.SuppressLint -import android.util.Log -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults -import androidx.compose.runtime.Composable -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.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.navigation.NavController -import com.example.moviestudio.Movie -import com.example.moviestudio.R -import com.example.moviestudio.ui.theme.dark -import com.example.moviestudio.ui.theme.main - -@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SearchMovie(navController: NavController) { - var isPopupVisible by remember { mutableStateOf(false) } - val appName = stringResource(id = R.string.app_name) - val pageName = stringResource(id = R.string.app_addMovie) - - var searchQuery by remember { mutableStateOf("") } - - var movieTitle by remember { mutableStateOf("Inception") } - var movieDescription by remember { mutableStateOf("Dom Cobb est un voleur expérimenté dans l'art périlleux de `l'extraction' : sa spécialité consiste à s'approprier les secrets les plus précieux d'un individu, enfouis au plus profond de son subconscient, pendant qu'il rêve et que son esprit est particulièrement vulnérable. Très recherché pour ses talents dans l'univers trouble de l'espionnage industriel, Cobb est aussi devenu un fugitif traqué dans le monde entier. Cependant, une ultime mission pourrait lui permettre de retrouver sa vie d'avant.") } - var moviePoster = "./poster" //painterResource(id = R.drawable.ic_launcher_background) - var movieReleaseDate = "10 juillet 2012" - var movieActors = "Leonardo Di Caprio, Marion Cotillard, Cilian Murphy, ..." - var movieGenres = "Thriller, Action, Intrigue, Amour, Science-fiction, ..." - - var movie = Movie( - id = 0, - name = movieTitle, - description = movieDescription, - poster = moviePoster, - releaseDate = movieReleaseDate, - actors = movieActors, - genres = movieGenres - ) - - Scaffold(modifier = Modifier, - topBar = { - if (!isPopupVisible) { - TopAppBar(colors = TopAppBarDefaults.smallTopAppBarColors( - containerColor = main, // Adjust color as needed - titleContentColor = Color.White, - ), title = { - Column { - Text(text = appName, fontSize = 24.sp) - Text(text = pageName, fontSize = 16.sp) - } - }) - } - }, - content = { - Column( - modifier = Modifier - .background(dark) - .fillMaxWidth() - .padding(4.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - if (!isPopupVisible) { - SearchMovieBar(searchQuery, onSearchQueryChange = { searchQuery = it }) - } - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .weight(1f) - ) { - items((0..3).toList()) { index -> - MovieCardSearch( - movie = movie, - onKnowMoreClick = { isPopupVisible = true }, - onAddToLibraryClick = { Log.i("SEARCH_MOVIE", "Add to library") } - ) - } - } - PreviewMovie( - isPopupVisible = isPopupVisible, - onCloseClick = { isPopupVisible = false }, - movie = movie - ) - Spacer(modifier = Modifier.height(55.dp)) - } - }, - bottomBar = { - BottomNavigation(navController = navController) - } - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SearchMovieBar(searchQuery: String, onSearchQueryChange: (String) -> Unit) { - val search = stringResource(id = R.string.app_search) - OutlinedTextField( - value = searchQuery, - onValueChange = { onSearchQueryChange(it) }, - label = { Text(search) }, - modifier = Modifier - .fillMaxWidth() - .padding(top = 55.dp) - .padding(8.dp), - textStyle = TextStyle(color = Color.White) - ) -} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/moviestudio/MainActivity.kt b/src/app/src/main/java/com/example/moviestudio/MainActivity.kt index c13b03f..daa14f0 100644 --- a/src/app/src/main/java/com/example/moviestudio/MainActivity.kt +++ b/src/app/src/main/java/com/example/moviestudio/MainActivity.kt @@ -7,9 +7,9 @@ import androidx.compose.runtime.Composable import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController -import com.example.moviestudio.Components.Library -import com.example.moviestudio.Components.SearchMovie -import com.example.moviestudio.Components.Settings +import com.example.moviestudio.ui.screens.Library +import com.example.moviestudio.ui.screens.SearchMovie +import com.example.moviestudio.ui.screens.Settings import com.example.moviestudio.ui.theme.MovieStudioTheme class MainActivity : ComponentActivity() { @@ -26,6 +26,7 @@ class MainActivity : ComponentActivity() { @Composable fun NavigationSetup() { val navController = rememberNavController() + NavHost( navController = navController, startDestination = "MainActivity" @@ -41,5 +42,3 @@ fun NavigationSetup() { } } } - - diff --git a/src/app/src/main/java/com/example/moviestudio/Components/BottomNavItem.kt b/src/app/src/main/java/com/example/moviestudio/ui/components/BottomNavItem.kt similarity index 81% rename from src/app/src/main/java/com/example/moviestudio/Components/BottomNavItem.kt rename to src/app/src/main/java/com/example/moviestudio/ui/components/BottomNavItem.kt index 50fd207..f887af8 100644 --- a/src/app/src/main/java/com/example/moviestudio/Components/BottomNavItem.kt +++ b/src/app/src/main/java/com/example/moviestudio/ui/components/BottomNavItem.kt @@ -1,30 +1,30 @@ -package com.example.moviestudio.Components - -import com.example.moviestudio.R - -sealed class BottomNavItem( - var title: String, - var icon: Int, - var activity: String -) { - object Library : - BottomNavItem( - "Library", - R.drawable.baseline_home_24, - "MainActivity" - ) - - object Search : - BottomNavItem( - "Search", - R.drawable.baseline_search_24, - "SearchMovieActivity" - ) - - object Settings : - BottomNavItem( - "Settings", - R.drawable.baseline_settings_24, - "SettingsActivity" - ) -} \ No newline at end of file +package com.example.moviestudio.ui.components + +import com.example.moviestudio.R + +sealed class BottomNavItem( + var title: String, + var icon: Int, + var activity: String +) { + object Library : + BottomNavItem( + "Bibliothèque", + R.drawable.baseline_home_24, + "MainActivity" + ) + + object Search : + BottomNavItem( + "Search", + R.drawable.baseline_search_24, + "SearchMovieActivity" + ) + + object Settings : + BottomNavItem( + "Paramètres", + R.drawable.baseline_settings_24, + "SettingsActivity" + ) +} diff --git a/src/app/src/main/java/com/example/moviestudio/Components/BottomNavigation.kt b/src/app/src/main/java/com/example/moviestudio/ui/components/BottomNavigation.kt similarity index 94% rename from src/app/src/main/java/com/example/moviestudio/Components/BottomNavigation.kt rename to src/app/src/main/java/com/example/moviestudio/ui/components/BottomNavigation.kt index e110fc8..1fc5db7 100644 --- a/src/app/src/main/java/com/example/moviestudio/Components/BottomNavigation.kt +++ b/src/app/src/main/java/com/example/moviestudio/ui/components/BottomNavigation.kt @@ -1,64 +1,63 @@ -package com.example.moviestudio.Components - -import android.util.Log -import androidx.compose.foundation.layout.RowScope -import androidx.compose.material3.Icon -import androidx.compose.material3.NavigationBar -import androidx.compose.material3.NavigationBarItem -import androidx.compose.material3.NavigationBarItemDefaults -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.navigation.NavController -import com.example.moviestudio.ui.theme.dark -import com.example.moviestudio.ui.theme.main - - -@Composable -fun BottomNavigation(navController: NavController) { - val items = listOf( - BottomNavItem.Library, - BottomNavItem.Search, - BottomNavItem.Settings, - ) - - NavigationBar(containerColor = dark) { - items.forEach { item -> - AddItem( - screen = item, - navController = navController - ) - } - } -} - -@Composable -fun RowScope.AddItem( - screen: BottomNavItem, - navController: NavController -) { - val isSelected = navController.currentDestination?.route == screen.activity - - NavigationBarItem( - label = { - Text(text = screen.title, color = Color.White) - }, - icon = { - Icon( - painterResource(id = screen.icon), - contentDescription = screen.title, - tint = Color.White - ) - }, - selected = isSelected, - alwaysShowLabel = true, - onClick = { - Log.i("NAV", screen.activity) - navController.navigate(screen.activity) - }, - colors = NavigationBarItemDefaults.colors( - indicatorColor = main - ) - ) -} \ No newline at end of file +package com.example.moviestudio.ui.components + +import android.util.Log +import androidx.compose.foundation.layout.RowScope +import androidx.compose.material3.Icon +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.NavigationBarItemDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.navigation.NavController +import com.example.moviestudio.ui.theme.dark +import com.example.moviestudio.ui.theme.main + +@Composable +fun BottomNavigation(navController: NavController) { + val items = listOf( + BottomNavItem.Library, + BottomNavItem.Search, + BottomNavItem.Settings, + ) + + NavigationBar(containerColor = dark) { + items.forEach { item -> + AddItem( + screen = item, + navController = navController + ) + } + } +} + +@Composable +fun RowScope.AddItem( + screen: BottomNavItem, + navController: NavController +) { + val isSelected = navController.currentDestination?.route == screen.activity + + NavigationBarItem( + label = { + Text(text = screen.title, color = Color.White) + }, + icon = { + Icon( + painterResource(id = screen.icon), + contentDescription = screen.title, + tint = Color.White + ) + }, + selected = isSelected, + alwaysShowLabel = true, + onClick = { + Log.i("NAV", screen.activity) + navController.navigate(screen.activity) + }, + colors = NavigationBarItemDefaults.colors( + indicatorColor = main + ) + ) +} diff --git a/src/app/src/main/java/com/example/moviestudio/Components/Components.kt b/src/app/src/main/java/com/example/moviestudio/ui/components/CommonComponents.kt similarity index 78% rename from src/app/src/main/java/com/example/moviestudio/Components/Components.kt rename to src/app/src/main/java/com/example/moviestudio/ui/components/CommonComponents.kt index 6c9d0e4..1b616fd 100644 --- a/src/app/src/main/java/com/example/moviestudio/Components/Components.kt +++ b/src/app/src/main/java/com/example/moviestudio/ui/components/CommonComponents.kt @@ -1,129 +1,150 @@ -package com.example.moviestudio.Components - -import android.annotation.SuppressLint -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.dp -import com.example.moviestudio.R - -@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SearchBarAndFilters( - searchQuery: String, - onSearchQueryChange: (String) -> Unit, - onDateSelected: (String) -> Unit, - onActorSelected: (String) -> Unit, - onGenreSelected: (String) -> Unit -) { - LazyRow( - modifier = Modifier - .fillMaxWidth() - ) { - item { - SearchBar(searchQuery, onSearchQueryChange = onSearchQueryChange) - } - item { - SearchDateReleased { selectedDate -> - onDateSelected(selectedDate) - } - } - item { - SearchActor { selectedActor -> - onActorSelected(selectedActor) - } - } - item { - SearchGenre { selectedGenre -> - onGenreSelected(selectedGenre) - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SearchBar(searchQuery: String, onSearchQueryChange: (String) -> Unit) { - val search = stringResource(id = R.string.app_search) - OutlinedTextField( - value = searchQuery, - onValueChange = { onSearchQueryChange(it) }, - label = { Text(search) }, - modifier = Modifier - .padding(top = 55.dp) - .padding(8.dp), - textStyle = TextStyle(color = Color.White) - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SearchDateReleased(onDateReleasedSelected: (String) -> Unit) { - var selectedDate by remember { mutableStateOf("") } - - OutlinedTextField( - value = selectedDate, - onValueChange = { newSelectedDate -> - selectedDate = newSelectedDate - onDateReleasedSelected(newSelectedDate) - }, - label = { Text("Date de sortie") }, - modifier = Modifier - .padding(8.dp) - .padding(top = 55.dp), - textStyle = TextStyle(color = Color.White) - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SearchActor(onActorSelected: (String) -> Unit) { - var actorName by remember { mutableStateOf("") } - - OutlinedTextField( - value = actorName, - onValueChange = { newActorName -> - actorName = newActorName - onActorSelected(newActorName) - }, - label = { Text("Acteur") }, - modifier = Modifier - .padding(8.dp) - .padding(top = 55.dp), - textStyle = TextStyle(color = Color.White) - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SearchGenre(onGenreSelected: (String) -> Unit) { - var genre by remember { mutableStateOf("") } - - OutlinedTextField( - value = genre, - onValueChange = { newGenre -> - genre = newGenre - onGenreSelected(newGenre) - }, - label = { Text("Genre") }, - modifier = Modifier - .padding(8.dp) - .padding(top = 55.dp), - textStyle = TextStyle(color = Color.White) - ) -} - - +package com.example.moviestudio.ui.components + +import android.annotation.SuppressLint +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.moviestudio.Movie +import com.example.moviestudio.R +import com.example.moviestudio.ui.theme.second + +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SearchBarAndFilters( + searchQuery: String, + onSearchQueryChange: (String) -> Unit, + onDateSelected: (String) -> Unit, + onActorSelected: (String) -> Unit, + onGenreSelected: (String) -> Unit +) { + LazyRow( + modifier = Modifier + .fillMaxWidth() + ) { + item { + SearchBar(searchQuery, onSearchQueryChange = onSearchQueryChange) + } + item { + SearchDateReleased { selectedDate -> + onDateSelected(selectedDate) + } + } + item { + SearchActor { selectedActor -> + onActorSelected(selectedActor) + } + } + item { + SearchGenre { selectedGenre -> + onGenreSelected(selectedGenre) + } + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SearchBar(searchQuery: String, onSearchQueryChange: (String) -> Unit) { + val search = stringResource(id = R.string.app_search) + OutlinedTextField( + value = searchQuery, + onValueChange = { onSearchQueryChange(it) }, + label = { Text(search) }, + modifier = Modifier + .padding(top = 55.dp) + .padding(8.dp), + textStyle = TextStyle(color = Color.White) + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SearchDateReleased(onDateReleasedSelected: (String) -> Unit) { + var selectedDate by remember { mutableStateOf("") } + + OutlinedTextField( + value = selectedDate, + onValueChange = { newSelectedDate -> + selectedDate = newSelectedDate + onDateReleasedSelected(newSelectedDate) + }, + label = { Text("Date de sortie") }, + modifier = Modifier + .padding(8.dp) + .padding(top = 55.dp), + textStyle = TextStyle(color = Color.White) + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SearchActor(onActorSelected: (String) -> Unit) { + var actorName by remember { mutableStateOf("") } + + OutlinedTextField( + value = actorName, + onValueChange = { newActorName -> + actorName = newActorName + onActorSelected(newActorName) + }, + label = { Text("Acteur") }, + modifier = Modifier + .padding(8.dp) + .padding(top = 55.dp), + textStyle = TextStyle(color = Color.White) + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SearchGenre(onGenreSelected: (String) -> Unit) { + var genre by remember { mutableStateOf("") } + + OutlinedTextField( + value = genre, + onValueChange = { newGenre -> + genre = newGenre + onGenreSelected(newGenre) + }, + label = { Text("Genre") }, + modifier = Modifier + .padding(8.dp) + .padding(top = 55.dp), + textStyle = TextStyle(color = Color.White) + ) +} + + diff --git a/src/app/src/main/java/com/example/moviestudio/ui/components/MovieCardComponent.kt b/src/app/src/main/java/com/example/moviestudio/ui/components/MovieCardComponent.kt new file mode 100644 index 0000000..542c899 --- /dev/null +++ b/src/app/src/main/java/com/example/moviestudio/ui/components/MovieCardComponent.kt @@ -0,0 +1,112 @@ +package com.example.moviestudio.ui.components + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Divider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.moviestudio.Movie +import com.example.moviestudio.R +import com.example.moviestudio.ui.theme.second + +@Composable +fun MovieCard( + movie: Movie, + onKnowMoreClick: () -> Unit, + modifier: Modifier = Modifier, + actionButton: (@Composable () -> Unit)? = null +) { + var poster = painterResource(id = R.drawable.ic_launcher_background) + + Box( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + .then(modifier) + ) { + Row() { + Image( + painter = poster, + contentDescription = "Movie Poster", + modifier = Modifier + .height(220.dp) + .width(120.dp) + .clip(MaterialTheme.shapes.medium), + contentScale = ContentScale.Crop + ) + + // Movie details on the right + Column( + modifier = Modifier + .fillMaxWidth() + .padding(start = 16.dp) + ) { + Text( + text = movie.name, + fontSize = 20.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ) + Text( + text = movie.description.take(120) + "...", + fontSize = 16.sp, + color = Color.White, + textAlign = TextAlign.Left + ) + + // Buttons + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(top = 10.dp) + ) { + Button( + onClick = onKnowMoreClick, + modifier = Modifier.fillMaxWidth(), + colors = ButtonDefaults.buttonColors(containerColor = second) + ) { + Text(text = stringResource(id = R.string.app_moreInformations)) + } + actionButton?.invoke() + } + } + } + } + } + Spacer(modifier = Modifier.height(2.dp)) + Divider( + color = Color.LightGray, + thickness = 0.01.dp, + modifier = Modifier + .fillMaxWidth() + .height(LocalDensity.current.density.dp) + ) +} diff --git a/src/app/src/main/java/com/example/moviestudio/Components/PopupComponent.kt b/src/app/src/main/java/com/example/moviestudio/ui/screens/LibraryScreen.kt similarity index 63% rename from src/app/src/main/java/com/example/moviestudio/Components/PopupComponent.kt rename to src/app/src/main/java/com/example/moviestudio/ui/screens/LibraryScreen.kt index 10e6cf5..de17972 100644 --- a/src/app/src/main/java/com/example/moviestudio/Components/PopupComponent.kt +++ b/src/app/src/main/java/com/example/moviestudio/ui/screens/LibraryScreen.kt @@ -1,463 +1,492 @@ -package com.example.moviestudio.Components - -import android.annotation.SuppressLint -import android.util.Log -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.DropdownMenu -import androidx.compose.material3.DropdownMenuItem -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults -import androidx.compose.runtime.Composable -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.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.example.moviestudio.Movie -import com.example.moviestudio.MovieWithGenres -import com.example.moviestudio.R -import com.example.moviestudio.UserRating -import com.example.moviestudio.ui.theme.dark -import com.example.moviestudio.ui.theme.main -import com.example.moviestudio.ui.theme.second -import com.example.moviestudio.ui.theme.third - -@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ShowMovie( - isPopupVisible: Boolean, - onCloseClick: () -> Unit, - movie: Movie, - userRating: UserRating -) { - var visibility = isPopupVisible - var isDropdownExpanded by remember { mutableStateOf(false) } - - var txtMovieDetails = stringResource(id = R.string.app_movieDetails) - var txtReleaseDate = stringResource(id = R.string.app_releaseDate) - - var ratingValue by remember { mutableStateOf(0) } - var commentValue by remember { mutableStateOf("") } - - - val density = LocalDensity.current.density - if (visibility) { - Scaffold( - modifier = Modifier.fillMaxSize(), - topBar = { - TopAppBar( - colors = TopAppBarDefaults.smallTopAppBarColors( - containerColor = main, - titleContentColor = Color.White, - ), - title = { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) - { - Text(text = txtMovieDetails) - IconButton(onClick = onCloseClick) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = null, - tint = Color.White - ) - } - } - } - ) - }, - content = { - Column( - modifier = Modifier - .background(color = dark) - .fillMaxWidth() - .padding(16.dp) - .verticalScroll(rememberScrollState()), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - IconButton(onClick = { - visibility = false - }) { - Icon(imageVector = Icons.Default.Close, contentDescription = null) - } - } - - Text(movie.name, fontSize = 26.sp, color = Color.White) - Text("$txtReleaseDate ${movie.releaseDate}", fontSize = 16.sp, color = Color.White) - - Spacer(modifier = Modifier.height(16.dp)) - Image( - painter = painterResource(id = R.drawable.ic_launcher_background), - contentDescription = "Movie Poster", - modifier = Modifier - .width((80 * density).dp) - .height((120 * density).dp) - .clip(shape = MaterialTheme.shapes.medium), - contentScale = ContentScale.Crop - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Text( - movie.description, - fontSize = 16.sp, - textAlign = TextAlign.Justify, - color = Color.White - ) - Spacer(modifier = Modifier.height(8.dp)) - Column( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - ) { - // Actors Section - Text( - "Acteurs", - fontSize = 16.sp, - textAlign = TextAlign.Start, - color = Color.White - ) - LazyRow(modifier = Modifier.padding(4.dp), userScrollEnabled = true) { - items(movie.actors.split(',')) { actor -> - Box( - modifier = Modifier - .padding(6.dp) - .border(1.dp, third, MaterialTheme.shapes.medium) - ) { - Text( - text = actor, - color = Color.White, - fontSize = 16.sp, - modifier = Modifier - .padding(8.dp) - ) - } - } - } - Spacer(modifier = Modifier.height(8.dp)) - - // Genres Section - Text( - "Genres", - fontSize = 16.sp, - textAlign = TextAlign.Start, - color = Color.White - ) - LazyRow(modifier = Modifier.padding(4.dp), userScrollEnabled = true) { - items(movie.genres.split(',')) { genre -> - Box( - modifier = Modifier - .padding(6.dp) - .border(1.dp, third, MaterialTheme.shapes.medium) - ) { - Text( - text = genre, - color = Color.White, - fontSize = 16.sp, - modifier = Modifier - .padding(8.dp) - ) - } - } - } - } - - - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - ) { - Row( - horizontalArrangement = Arrangement.spacedBy(5.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - - Column( - verticalArrangement = Arrangement.spacedBy(4.dp), - horizontalAlignment = Alignment.Start - ) { - Text( - text = "Note", - color = Color.White, - fontSize = 16.sp, - modifier = Modifier.padding(6.dp, 4.dp, 6.dp, 4.dp) - ) - - Column { - Box( - modifier = Modifier - .width(65.dp) - .padding(6.dp, 8.dp, 6.dp, 8.dp) - .background(dark) - .clickable { isDropdownExpanded = true } - .border(1.dp, Color.White, MaterialTheme.shapes.medium) - ) { - Text( - text = userRating.rating.toString(), - color = Color.White, - modifier = Modifier.padding(16.dp) - ) - } - - DropdownMenu( - expanded = isDropdownExpanded, - onDismissRequest = { isDropdownExpanded = false }, - modifier = Modifier - .width(65.dp) - .background(dark) - ) { - for (i in 0..5) { - DropdownMenuItem( - onClick = { - ratingValue = i - isDropdownExpanded = false - }, - text = { - Text(i.toString(), color = Color.White) - }) - } - } - } - } - - Column( - verticalArrangement = Arrangement.spacedBy(4.dp), - horizontalAlignment = Alignment.Start - ) { - Text( - text = "Comment", - color = Color.White, - fontSize = 16.sp, - modifier = Modifier.padding(4.dp) - ) - - // Text field to input a comment - OutlinedTextField( - value = commentValue, - onValueChange = { commentValue = it }, - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .border(1.dp, Color.White, MaterialTheme.shapes.medium), - textStyle = TextStyle(color = Color.White) - ) - } - } - - // Button to save - Button( - onClick = { Log.i("LIBRARY", "Save informations about the movie") }, - modifier = Modifier - .fillMaxWidth() - .padding(2.dp), - colors = ButtonDefaults.buttonColors(containerColor = second) - ) { - Text("Save") - } - Spacer(modifier = Modifier.height(65.dp)) - } - } - } - ) - } -} - -@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PreviewMovie( - isPopupVisible: Boolean, - onCloseClick: () -> Unit, - movie: Movie -) { - var visibility = isPopupVisible - var movieDetails = stringResource(id = R.string.app_moreInformations) - var releaseDate = stringResource(id = R.string.app_releaseDate) - - val density = LocalDensity.current.density - if (visibility) { - Scaffold( - modifier = Modifier.fillMaxSize(), - topBar = { - TopAppBar( - colors = TopAppBarDefaults.smallTopAppBarColors( - containerColor = main, - titleContentColor = Color.White, - ), - title = { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) - { - Text(text = movieDetails) // Modify as needed - IconButton(onClick = onCloseClick) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = null, - tint = Color.White - ) - } - } - } - ) - }, - content = { - Column( - modifier = Modifier - .background(color = dark) - .fillMaxWidth() - .fillMaxHeight() - .padding(16.dp) - .verticalScroll(rememberScrollState()), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - IconButton(onClick = { - visibility = false - }) { - Icon(imageVector = Icons.Default.Close, contentDescription = null) - } - } - - Text(movie.name, fontSize = 26.sp, color = Color.White) - Text("$releaseDate ${movie.releaseDate}", fontSize = 16.sp, color = Color.White) - - Spacer(modifier = Modifier.height(16.dp)) - Image( - painter = painterResource(id = R.drawable.ic_launcher_background), - contentDescription = "Movie Poster", - modifier = Modifier - .width((80 * density).dp) - .height((120 * density).dp) - .clip(shape = MaterialTheme.shapes.medium), - contentScale = ContentScale.Crop - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Text( - movie.description, - fontSize = 16.sp, - textAlign = TextAlign.Justify, - color = Color.White - ) - Spacer(modifier = Modifier.height(8.dp)) - Column( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - ) { - // Actors Section - Text( - "Acteurs", - fontSize = 16.sp, - textAlign = TextAlign.Start, - color = Color.White - ) - LazyRow(modifier = Modifier.padding(4.dp), userScrollEnabled = true) { - items(movie.actors.split(',')) { actor -> - Box( - modifier = Modifier - .padding(6.dp) - .border(1.dp, third, MaterialTheme.shapes.medium) - ) { - Text( - text = actor, - color = Color.White, - fontSize = 16.sp, - modifier = Modifier - .padding(8.dp) - ) - } - } - } - Spacer(modifier = Modifier.height(8.dp)) - - // Genres Section - Text( - "Genres", - fontSize = 16.sp, - textAlign = TextAlign.Start, - color = Color.White - ) - LazyRow(modifier = Modifier.padding(4.dp), userScrollEnabled = true) { - items(movie.genres.split(',')) { genre -> - Box( - modifier = Modifier - .padding(8.dp) - .border(1.dp, third, MaterialTheme.shapes.medium) - ) { - Text( - text = genre, - color = Color.White, - fontSize = 16.sp, - modifier = Modifier - .padding(8.dp) - ) - } - } - } - Spacer(modifier = Modifier.height(55.dp)) - } - } - } - ) - } -} \ No newline at end of file +package com.example.moviestudio.ui.screens + +import android.annotation.SuppressLint +import android.util.Log +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Close +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Divider +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +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.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavController +import com.example.moviestudio.Movie +import com.example.moviestudio.R +import com.example.moviestudio.UserRating +import com.example.moviestudio.ui.components.BottomNavigation +import com.example.moviestudio.ui.components.SearchBarAndFilters +import com.example.moviestudio.ui.theme.dark +import com.example.moviestudio.ui.theme.main +import com.example.moviestudio.ui.theme.second +import com.example.moviestudio.ui.theme.third +import com.example.moviestudio.viewmodels.LibraryViewModel +import com.example.moviestudio.viewmodels.ShowMovieViewModel + +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Library(navController: NavController) { + val appName = stringResource(id = R.string.app_name) + val pageName = stringResource(id = R.string.app_library) + + val viewModel = viewModel<LibraryViewModel>() + + Scaffold( + modifier = Modifier, + topBar = { + if (!viewModel.isPopupVisible) { + TopAppBar(colors = TopAppBarDefaults.smallTopAppBarColors( + containerColor = main, + titleContentColor = Color.White, + ), title = { + Column { + Text(text = appName, fontSize = 24.sp) + Text(text = pageName, fontSize = 16.sp) + } + } + ) + } + }, + content = { + // Content with a Column containing search components and LazyColumn + Column( + modifier = Modifier + .background(dark) + .fillMaxSize() + .padding(4.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + if (!viewModel.isPopupVisible) { + SearchBarAndFilters( + searchQuery = viewModel.searchQuery, + onSearchQueryChange = { viewModel.updateSearchQuery(it) }, + onDateSelected = { viewModel.updateSearchPublishDate(it) }, + onActorSelected = { viewModel.updateSearchActor(it) }, + onGenreSelected = { viewModel.updateSearchGenre(it) } + ) + } + + // Display movies saved in the library. + LazyColumn( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + ) { + items(viewModel.movies) { movie -> + MovieCardLibrary( + movie = movie, + onKnowMoreClick = { + viewModel.updateSelectedMovie(movie) + viewModel.showMovieDetails() + }, + onDeleteClick = { + // TODO + } + ) + } + } + + ShowMovie( + isModalVisible = viewModel.isPopupVisible, + onCloseClick = { viewModel.hideMovieDetails() }, + movie = viewModel.selectedMovie + ) + Spacer(modifier = Modifier.height(55.dp)) + } + }, + bottomBar = { + BottomNavigation(navController = navController) + } + ) +} + +@Composable +fun MovieCardLibrary( + movie: Movie, + onKnowMoreClick: () -> Unit, + onDeleteClick: () -> Unit +) { + // TODO : use movie.poster + var poster = painterResource(id = R.drawable.ic_launcher_background) + + Box( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + ) { + // Movie poster on the left + Image( + painter = poster, + contentDescription = "Movie Poster", + modifier = Modifier + .height(220.dp) + .width(120.dp) + .clip(MaterialTheme.shapes.medium), + contentScale = ContentScale.Crop + ) + + // Movie details in the middle + Column( + modifier = Modifier + .fillMaxWidth() + .padding(start = 16.dp) + ) { + Text( + text = movie.name, + fontSize = 20.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ) + Text( + text = movie.description.take(120) + "...", + fontSize = 16.sp, + color = Color.White, + textAlign = TextAlign.Left, + modifier = Modifier.padding(top = 6.dp) + ) + + // Buttons + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Column( + modifier = Modifier.fillMaxWidth() + ) { + Button( + onClick = onKnowMoreClick, + modifier = Modifier.fillMaxWidth(), + colors = ButtonDefaults.buttonColors(containerColor = second) + ) { + Text(text = "Plus d'informations") + } + } + } + } + } + + // Trash icon in the top-right corner + Icon( + painter = painterResource(id = R.drawable.baseline_delete_24), + contentDescription = "Delete", + modifier = Modifier + .padding(8.dp) + .size(24.dp) + .clickable { onDeleteClick() } + .align(Alignment.TopEnd), + tint = Color.White, + ) + } + + Spacer(modifier = Modifier.height(2.dp)) + Divider( + color = Color.LightGray, + thickness = 0.01.dp, + modifier = Modifier + .fillMaxWidth() + .height(LocalDensity.current.density.dp) + ) +} + +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ShowMovie( + isModalVisible: Boolean, + onCloseClick: () -> Unit, + movie: Movie +) { + val viewModel = viewModel<ShowMovieViewModel>() + viewModel.movie = movie + + // UI-related variables: + val density = LocalDensity.current.density + + if (isModalVisible) { + Scaffold( + modifier = Modifier.fillMaxSize(), + topBar = { + TopAppBar( + colors = TopAppBarDefaults.smallTopAppBarColors( + containerColor = main, + titleContentColor = Color.White, + ), + title = { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) + { + Text(text = movie.name) + IconButton(onClick = onCloseClick) { + Icon( + imageVector = Icons.Default.Close, + contentDescription = null, + tint = Color.White + ) + } + } + } + ) + }, + content = { + Column( + modifier = Modifier + .background(color = dark) + .fillMaxWidth() + .padding(16.dp) + .verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + IconButton(onClick = {}) { + Icon(imageVector = Icons.Default.Close, contentDescription = null) + } + } + + Text(movie.name, fontSize = 26.sp, color = Color.White) + Text( + "Sortie le ${movie.releaseDate}", + fontSize = 16.sp, + color = Color.White + ) + + Spacer(modifier = Modifier.height(16.dp)) + Image( + painter = painterResource(id = R.drawable.ic_launcher_background), + contentDescription = "Movie Poster", + modifier = Modifier + .width((80 * density).dp) + .height((120 * density).dp) + .clip(shape = MaterialTheme.shapes.medium), + contentScale = ContentScale.Crop + ) + + Spacer(modifier = Modifier.height(16.dp)) + + Text( + movie.description, + fontSize = 16.sp, + textAlign = TextAlign.Justify, + color = Color.White + ) + Spacer(modifier = Modifier.height(8.dp)) + Column( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + ) { + // Actors Section + Text( + "Acteurs", + fontSize = 16.sp, + textAlign = TextAlign.Start, + color = Color.White + ) + LazyRow(modifier = Modifier.padding(4.dp), userScrollEnabled = true) { + items(movie.actors.split(',')) { actor -> + Box( + modifier = Modifier + .padding(6.dp) + .border(1.dp, third, MaterialTheme.shapes.medium) + ) { + Text( + text = actor, + color = Color.White, + fontSize = 16.sp, + modifier = Modifier + .padding(8.dp) + ) + } + } + } + Spacer(modifier = Modifier.height(8.dp)) + + // Genres Section + Text( + "Genres", + fontSize = 16.sp, + textAlign = TextAlign.Start, + color = Color.White + ) + LazyRow(modifier = Modifier.padding(4.dp), userScrollEnabled = true) { + items(movie.genres.split(',')) { genre -> + Box( + modifier = Modifier + .padding(6.dp) + .border(1.dp, third, MaterialTheme.shapes.medium) + ) { + Text( + text = genre, + color = Color.White, + fontSize = 16.sp, + modifier = Modifier + .padding(8.dp) + ) + } + } + } + } + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(5.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + horizontalAlignment = Alignment.Start + ) { + Text( + text = "Note", + color = Color.White, + fontSize = 16.sp, + modifier = Modifier.padding(6.dp, 4.dp, 6.dp, 4.dp) + ) + + Column { + Box( + modifier = Modifier + .width(65.dp) + .padding(6.dp, 8.dp, 6.dp, 8.dp) + .background(dark) + .clickable { viewModel.updateIsDropdownExpanded(true) } + .border(1.dp, Color.White, MaterialTheme.shapes.medium) + ) { + Text( + text = viewModel.ratingValue.toString(), + color = Color.White, + modifier = Modifier.padding(16.dp) + ) + } + + DropdownMenu( + expanded = viewModel.isDropdownExpanded, + onDismissRequest = { + viewModel.updateIsDropdownExpanded( + false + ) + }, + modifier = Modifier + .width(65.dp) + .background(dark) + ) { + for (i in 1..5) { + DropdownMenuItem( + onClick = { + viewModel.updateRatingValue(i) + viewModel.updateIsDropdownExpanded(false) + }, + text = { + Text(i.toString(), color = Color.White) + }) + } + } + } + } + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + horizontalAlignment = Alignment.Start + ) { + Text( + text = "Comment", + color = Color.White, + fontSize = 16.sp, + modifier = Modifier.padding(4.dp) + ) + + // Text field to input a comment + OutlinedTextField( + value = viewModel.commentValue, + onValueChange = { viewModel.updateCommentValue(it) }, + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .border(1.dp, Color.White, MaterialTheme.shapes.medium), + textStyle = TextStyle(color = Color.White) + ) + } + } + + // Button to save + Button( + onClick = { Log.i("LIBRARY", "Save informations about the movie") }, + modifier = Modifier + .fillMaxWidth() + .padding(2.dp), + colors = ButtonDefaults.buttonColors(containerColor = second) + ) { + Text("Save") + } + Spacer(modifier = Modifier.height(65.dp)) + } + } + } + ) + } +} diff --git a/src/app/src/main/java/com/example/moviestudio/ui/screens/SearchMovieScreen.kt b/src/app/src/main/java/com/example/moviestudio/ui/screens/SearchMovieScreen.kt new file mode 100644 index 0000000..c0d9814 --- /dev/null +++ b/src/app/src/main/java/com/example/moviestudio/ui/screens/SearchMovieScreen.kt @@ -0,0 +1,322 @@ +package com.example.moviestudio.ui.screens + +import android.annotation.SuppressLint +import android.util.Log +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Close +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +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.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavController +import com.example.moviestudio.Movie +import com.example.moviestudio.R +import com.example.moviestudio.ui.components.BottomNavigation +import com.example.moviestudio.ui.components.MovieCard +import com.example.moviestudio.ui.theme.dark +import com.example.moviestudio.ui.theme.main +import com.example.moviestudio.ui.theme.second +import com.example.moviestudio.ui.theme.third +import com.example.moviestudio.viewmodels.SearchMovieViewModel +import com.example.moviestudio.viewmodels.SettingsViewModel + +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SearchMovie(navController: NavController) { + val appName = stringResource(id = R.string.app_name) + val pageName = stringResource(id = R.string.app_addMovie) + + val viewModel = viewModel<SearchMovieViewModel>() + + + Scaffold(modifier = Modifier, + topBar = { + if (!viewModel.isPopupVisible) { + TopAppBar(colors = TopAppBarDefaults.smallTopAppBarColors( + containerColor = main, + titleContentColor = Color.White, + ), title = { + Column { + Text(text = appName, fontSize = 24.sp) + Text(text = pageName, fontSize = 16.sp) + } + }) + } + }, + content = { + Column( + modifier = Modifier + .background(dark) + .fillMaxWidth() + .padding(4.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + if (!viewModel.isPopupVisible) { + SearchMovieBar( + viewModel.searchQuery, + onSearchQueryChange = { viewModel.updateSearchQuery(it) } + ) + } + + LazyColumn( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + ) { + // TODO : use list of MovieApiResult + items((0..3).toList()) { index -> + MovieCardSearch( + movie = viewModel.selectedMovie, + onKnowMoreClick = { viewModel.showMoviePreview() }, + onAddToLibraryClick = { Log.i("SEARCH_MOVIE", "Add to library") } + ) + } + } + + PreviewMovie( + isPopupVisible = viewModel.isPopupVisible, + onCloseClick = { viewModel.hideMoviePreview() }, + movie = viewModel.selectedMovie + ) + Spacer(modifier = Modifier.height(55.dp)) + } + }, + bottomBar = { + BottomNavigation(navController = navController) + } + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SearchMovieBar(searchQuery: String, onSearchQueryChange: (String) -> Unit) { + val search = stringResource(id = R.string.app_search) + OutlinedTextField( + value = searchQuery, + onValueChange = { onSearchQueryChange(it) }, + label = { Text(search) }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 55.dp) + .padding(8.dp), + textStyle = TextStyle(color = Color.White) + ) +} + +@Composable +fun MovieCardSearch( + movie: Movie, + onKnowMoreClick: () -> Unit, + onAddToLibraryClick: () -> Unit +) { + MovieCard( + movie = movie, + onKnowMoreClick = onKnowMoreClick, + actionButton = { + Button( + onClick = onAddToLibraryClick, + modifier = Modifier.fillMaxWidth(), + colors = ButtonDefaults.buttonColors(containerColor = second) + ) { + Text(text = stringResource(id = R.string.app_library)) + Icon( + imageVector = Icons.Default.Add, + contentDescription = null, + tint = Color.White + ) + } + } + ) +} + +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun PreviewMovie( + isPopupVisible: Boolean, + onCloseClick: () -> Unit, + movie: Movie +) { + // UI-related variables: + val density = LocalDensity.current.density + + if (isPopupVisible) { + Scaffold( + modifier = Modifier.fillMaxSize(), + topBar = { + TopAppBar( + colors = TopAppBarDefaults.smallTopAppBarColors( + containerColor = main, + titleContentColor = Color.White, + ), + title = { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) + { + Text(text = "En savoir plus") + IconButton(onClick = onCloseClick) { + Icon( + imageVector = Icons.Default.Close, + contentDescription = null, + tint = Color.White + ) + } + } + } + ) + }, + content = { + Column( + modifier = Modifier + .background(color = dark) + .fillMaxWidth() + .fillMaxHeight() + .padding(16.dp) + .verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + IconButton(onClick = {}) { + Icon(imageVector = Icons.Default.Close, contentDescription = null) + } + } + + Text(movie.name, fontSize = 26.sp, color = Color.White) + Text("Sortie le ${movie.releaseDate}", fontSize = 16.sp, color = Color.White) + + Spacer(modifier = Modifier.height(16.dp)) + Image( + painter = painterResource(id = R.drawable.ic_launcher_background), + contentDescription = "Movie Poster", + modifier = Modifier + .width((80 * density).dp) + .height((120 * density).dp) + .clip(shape = MaterialTheme.shapes.medium), + contentScale = ContentScale.Crop + ) + + Spacer(modifier = Modifier.height(16.dp)) + + Text( + movie.description, + fontSize = 16.sp, + textAlign = TextAlign.Justify, + color = Color.White + ) + Spacer(modifier = Modifier.height(8.dp)) + Column( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + ) { + // Actors Section + Text( + "Acteurs", + fontSize = 16.sp, + textAlign = TextAlign.Start, + color = Color.White + ) + LazyRow(modifier = Modifier.padding(4.dp), userScrollEnabled = true) { + items(movie.actors.split(',')) { actor -> + Box( + modifier = Modifier + .padding(6.dp) + .border(1.dp, third, MaterialTheme.shapes.medium) + ) { + Text( + text = actor, + color = Color.White, + fontSize = 16.sp, + modifier = Modifier + .padding(8.dp) + ) + } + } + } + Spacer(modifier = Modifier.height(8.dp)) + + // Genres Section + Text( + "Genres", + fontSize = 16.sp, + textAlign = TextAlign.Start, + color = Color.White + ) + LazyRow(modifier = Modifier.padding(4.dp), userScrollEnabled = true) { + items(movie.genres.split(',')) { genre -> + Box( + modifier = Modifier + .padding(8.dp) + .border(1.dp, third, MaterialTheme.shapes.medium) + ) { + Text( + text = genre, + color = Color.White, + fontSize = 16.sp, + modifier = Modifier + .padding(8.dp) + ) + } + } + } + Spacer(modifier = Modifier.height(55.dp)) + } + } + } + ) + } +} diff --git a/src/app/src/main/java/com/example/moviestudio/Components/SettingsComponent.kt b/src/app/src/main/java/com/example/moviestudio/ui/screens/SettingsScreen.kt similarity index 86% rename from src/app/src/main/java/com/example/moviestudio/Components/SettingsComponent.kt rename to src/app/src/main/java/com/example/moviestudio/ui/screens/SettingsScreen.kt index 3d15471..98bd034 100644 --- a/src/app/src/main/java/com/example/moviestudio/Components/SettingsComponent.kt +++ b/src/app/src/main/java/com/example/moviestudio/ui/screens/SettingsScreen.kt @@ -1,81 +1,85 @@ -package com.example.moviestudio.Components - -import android.annotation.SuppressLint -import android.util.Log -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.navigation.NavController -import com.example.moviestudio.R -import com.example.moviestudio.ui.theme.dark -import com.example.moviestudio.ui.theme.main -import com.example.moviestudio.ui.theme.second - -@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun Settings(navController: NavController) { - - val appName = stringResource(id = R.string.app_name) - val pageName = stringResource(id = R.string.app_settings) - val btnText = stringResource(id = R.string.app_clearData) - - Scaffold( - modifier = Modifier.background(Color.Black), - topBar = { - TopAppBar( - colors = TopAppBarDefaults.smallTopAppBarColors( - containerColor = main, - titleContentColor = Color.White, - ), - title = { - Column { - Text(text = appName, fontSize = 24.sp) - Text(text = pageName, fontSize = 16.sp) - } - } - ) - }, - content = { - // Content with a Column containing a Button - Column( - modifier = Modifier - .background(color = dark) - .fillMaxSize() - .padding(start = 10.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - Button( - modifier = Modifier - .fillMaxWidth() - .padding(6.dp), - onClick = { Log.i("SETTINGS", "Clear database") }, - colors = ButtonDefaults.buttonColors(containerColor = second) - ) { - Text(text = btnText) - } - } - }, - bottomBar = { - BottomNavigation(navController = navController) - } - ) -} \ No newline at end of file +package com.example.moviestudio.ui.screens + +import android.annotation.SuppressLint +import android.util.Log +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavController +import com.example.moviestudio.R +import com.example.moviestudio.ui.components.BottomNavigation +import com.example.moviestudio.ui.theme.dark +import com.example.moviestudio.ui.theme.main +import com.example.moviestudio.ui.theme.second +import com.example.moviestudio.viewmodels.LibraryViewModel +import com.example.moviestudio.viewmodels.SettingsViewModel + +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Settings(navController: NavController) { + val appName = stringResource(id = R.string.app_name) + val pageName = stringResource(id = R.string.app_settings) + + val viewModel = viewModel<SettingsViewModel>() + + Scaffold( + modifier = Modifier.background(Color.Black), + topBar = { + TopAppBar( + colors = TopAppBarDefaults.smallTopAppBarColors( + containerColor = main, + titleContentColor = Color.White, + ), + title = { + Column { + Text(text = appName, fontSize = 24.sp) + Text(text = pageName, fontSize = 16.sp) + } + } + ) + }, + content = { + // Content with a Column containing a Button + Column( + modifier = Modifier + .background(color = dark) + .fillMaxSize() + .padding(start = 10.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Button( + modifier = Modifier + .fillMaxWidth() + .padding(6.dp), + onClick = { viewModel.deleteAppData() }, + colors = ButtonDefaults.buttonColors(containerColor = second) + ) { + Text(text = "Supprimer les données") + } + } + }, + bottomBar = { + BottomNavigation(navController = navController) + } + ) +} diff --git a/src/app/src/main/java/com/example/moviestudio/viewmodels/LibraryViewModel.kt b/src/app/src/main/java/com/example/moviestudio/viewmodels/LibraryViewModel.kt new file mode 100644 index 0000000..47bd3ac --- /dev/null +++ b/src/app/src/main/java/com/example/moviestudio/viewmodels/LibraryViewModel.kt @@ -0,0 +1,99 @@ +package com.example.moviestudio.viewmodels + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.lifecycle.ViewModel +import com.example.moviestudio.Movie +import com.example.moviestudio.UserRating + +class LibraryViewModel : ViewModel() { + var searchQuery by mutableStateOf("") + private set + var searchPublishDate by mutableStateOf("") + private set + var searchActor by mutableStateOf("") + private set + var searchGenre by mutableStateOf("") + private set + + var isPopupVisible by mutableStateOf(false) + private set + + val movie = Movie( + id = 1, + name = "Inception", + description = "Dom Cobb est un voleur expérimenté dans l'art périlleux de `l'extraction' : sa spécialité consiste à s'approprier les secrets les plus précieux d'un individu, enfouis au plus profond de son subconscient, pendant qu'il rêve et que son esprit est particulièrement vulnérable. Très recherché pour ses talents dans l'univers trouble de l'espionnage industriel, Cobb est aussi devenu un fugitif traqué dans le monde entier. Cependant, une ultime mission pourrait lui permettre de retrouver sa vie d'avant.", + poster = "./poster", + releaseDate = "10 juillet 2012", + actors = "Leonardo Di Caprio, Marion Cotillard, Cilian Murphy, ...", + genres = "Thriller, Action, Intrigue, Amour, Science-fiction, ..." + ) + + val movies = listOf<Movie>( + Movie( + id = 1, + name = "Movie A", + description = "Dom Cobb est un voleur expérimenté dans l'art périlleux de `l'extraction' : sa spécialité consiste à s'approprier les secrets les plus précieux d'un individu, enfouis au plus profond de son subconscient, pendant qu'il rêve et que son esprit est particulièrement vulnérable. Très recherché pour ses talents dans l'univers trouble de l'espionnage industriel, Cobb est aussi devenu un fugitif traqué dans le monde entier. Cependant, une ultime mission pourrait lui permettre de retrouver sa vie d'avant.", + poster = "./poster", + releaseDate = "10 juillet 2012", + actors = "Leonardo Di Caprio, Marion Cotillard, Cilian Murphy, ...", + genres = "Thriller, Action, Intrigue, Amour, Science-fiction, ..." + ), + Movie( + id = 2, + name = "Movie B", + description = "Dom Cobb est un voleur expérimenté dans l'art périlleux de `l'extraction' : sa spécialité consiste à s'approprier les secrets les plus précieux d'un individu, enfouis au plus profond de son subconscient, pendant qu'il rêve et que son esprit est particulièrement vulnérable. Très recherché pour ses talents dans l'univers trouble de l'espionnage industriel, Cobb est aussi devenu un fugitif traqué dans le monde entier. Cependant, une ultime mission pourrait lui permettre de retrouver sa vie d'avant.", + poster = "./poster", + releaseDate = "10 juillet 2012", + actors = "Leonardo Di Caprio, Marion Cotillard, Cilian Murphy, ...", + genres = "Thriller, Action, Intrigue, Amour, Science-fiction, ..." + ), + Movie( + id = 3, + name = "Movie C", + description = "Dom Cobb est un voleur expérimenté dans l'art périlleux de `l'extraction' : sa spécialité consiste à s'approprier les secrets les plus précieux d'un individu, enfouis au plus profond de son subconscient, pendant qu'il rêve et que son esprit est particulièrement vulnérable. Très recherché pour ses talents dans l'univers trouble de l'espionnage industriel, Cobb est aussi devenu un fugitif traqué dans le monde entier. Cependant, une ultime mission pourrait lui permettre de retrouver sa vie d'avant.", + poster = "./poster", + releaseDate = "10 juillet 2012", + actors = "Leonardo Di Caprio, Marion Cotillard, Cilian Murphy, ...", + genres = "Thriller, Action, Intrigue, Amour, Science-fiction, ..." + ), + ) + + var selectedMovie by mutableStateOf(movies[0]) + + val userRating = UserRating( + id = 1, + comment = "", + rating = 3, + movieId = 1 + ) + + fun updateSearchQuery(value: String) { + searchQuery = value + } + + fun updateSearchPublishDate(value: String) { + searchPublishDate = value + } + + fun updateSearchActor(value: String) { + searchActor = value + } + + fun updateSearchGenre(value: String) { + searchGenre = value + } + + fun updateSelectedMovie(value: Movie) { + selectedMovie = value + } + + fun showMovieDetails() { + isPopupVisible = true + } + + fun hideMovieDetails() { + isPopupVisible = false + } +} diff --git a/src/app/src/main/java/com/example/moviestudio/viewmodels/SearchMovieViewModel.kt b/src/app/src/main/java/com/example/moviestudio/viewmodels/SearchMovieViewModel.kt new file mode 100644 index 0000000..f96b914 --- /dev/null +++ b/src/app/src/main/java/com/example/moviestudio/viewmodels/SearchMovieViewModel.kt @@ -0,0 +1,40 @@ +package com.example.moviestudio.viewmodels + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.lifecycle.ViewModel +import com.example.moviestudio.Movie + +class SearchMovieViewModel : ViewModel() { + var isPopupVisible by mutableStateOf(false) + private set + + var searchQuery by mutableStateOf("") + private set + + var selectedMovie by mutableStateOf( + Movie( + id = 3, + name = "Movie C", + description = "Dom Cobb est un voleur expérimenté dans l'art périlleux de `l'extraction' : sa spécialité consiste à s'approprier les secrets les plus précieux d'un individu, enfouis au plus profond de son subconscient, pendant qu'il rêve et que son esprit est particulièrement vulnérable. Très recherché pour ses talents dans l'univers trouble de l'espionnage industriel, Cobb est aussi devenu un fugitif traqué dans le monde entier. Cependant, une ultime mission pourrait lui permettre de retrouver sa vie d'avant.", + poster = "./poster", + releaseDate = "10 juillet 2012", + actors = "Leonardo Di Caprio, Marion Cotillard, Cilian Murphy, ...", + genres = "Thriller, Action, Intrigue, Amour, Science-fiction, ..." + ) + ) + + fun updateSearchQuery(value: String) { + searchQuery = value + } + + fun showMoviePreview() { + isPopupVisible = true + } + + fun hideMoviePreview() { + isPopupVisible = false + } +} diff --git a/src/app/src/main/java/com/example/moviestudio/viewmodels/SettingsViewModel.kt b/src/app/src/main/java/com/example/moviestudio/viewmodels/SettingsViewModel.kt new file mode 100644 index 0000000..7f79204 --- /dev/null +++ b/src/app/src/main/java/com/example/moviestudio/viewmodels/SettingsViewModel.kt @@ -0,0 +1,9 @@ +package com.example.moviestudio.viewmodels + +import androidx.lifecycle.ViewModel + +class SettingsViewModel : ViewModel() { + fun deleteAppData() { + // TODO + } +} diff --git a/src/app/src/main/java/com/example/moviestudio/viewmodels/ShowMovieViewModel.kt b/src/app/src/main/java/com/example/moviestudio/viewmodels/ShowMovieViewModel.kt new file mode 100644 index 0000000..7ed6115 --- /dev/null +++ b/src/app/src/main/java/com/example/moviestudio/viewmodels/ShowMovieViewModel.kt @@ -0,0 +1,35 @@ +package com.example.moviestudio.viewmodels + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.lifecycle.ViewModel +import com.example.moviestudio.Movie + +class ShowMovieViewModel: ViewModel() { + var movie: Movie? = null + + var isDropdownExpanded by mutableStateOf(false) + private set + + var ratingValue by mutableStateOf(1) + private set + + var commentValue by mutableStateOf("") + private set + + fun updateIsDropdownExpanded(value: Boolean) { + isDropdownExpanded = value + } + + fun updateRatingValue(value: Int) { + // TODO : use rating model + ratingValue = value + } + + fun updateCommentValue(value: String) { + // TODO : use rating model + commentValue = value + } +} -- GitLab