V1 fonctionnelle

This commit is contained in:
MalcuitEmile
2025-12-17 17:58:53 +01:00
parent 9c6e229826
commit 190380dc4a
3 changed files with 243 additions and 72 deletions

View File

@@ -53,6 +53,7 @@ dependencies {
implementation(libs.androidx.compose.ui.graphics)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.ui.graphics)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)

View File

@@ -4,7 +4,8 @@ import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -14,13 +15,17 @@ 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.items
import androidx.compose.material3.Button
import androidx.compose.material3.Divider
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
@@ -29,22 +34,28 @@ 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.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModelProvider
import com.dev.collectiondvd.data.local.AppDatabase
import com.dev.collectiondvd.data.local.entities.Dvd
import com.dev.collectiondvd.data.repository.LocalDvdRepository
import com.dev.collectiondvd.ui.screen.AjoutDvdActivity
import com.dev.collectiondvd.ui.screen.SupprDvdActivity
import com.dev.collectiondvd.ui.theme.CollectionDvdTheme
import com.dev.collectiondvd.ui.theme.MyButton
import com.dev.collectiondvd.viewmodel.LocalDvdViewModel
import com.dev.collectiondvd.viewmodel.factory.LocalDvdViewModelFactory
import java.nio.file.WatchEvent
import kotlin.system.exitProcess
import androidx.compose.material3.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
class MainActivity : ComponentActivity() {
private lateinit var viewModel: LocalDvdViewModel
@@ -55,11 +66,32 @@ class MainActivity : ComponentActivity() {
val repository = LocalDvdRepository(dvdDao)
val factory = LocalDvdViewModelFactory(repository)
viewModel = ViewModelProvider(this, factory).get(LocalDvdViewModel::class.java)
setContent { MenuScreen(onQuit = { finish() }, viewModel = viewModel) }
setContent {
CollectionDvdTheme(darkTheme = true) {
MenuScreen(
onQuit = { finish() },
viewModel = viewModel
)
}
}
}
}
enum class SortType(
val label: String
) {
TITLE_ASC("Titre (ascendant)"),
TITLE_DESC("Titre (descendant)"),
DIRECTOR_ASC("Réalisateur (ascendant)"),
DIRECTOR_DESC("Réalisateur (descendant)"),
YEAR_ASC("Année (ascendant)"),
YEAR_DESC("Année (descendant)")
}
@Composable
fun MenuScreen(
viewModel: LocalDvdViewModel,
@@ -69,86 +101,222 @@ fun MenuScreen(
val dvds by viewModel.dvds.collectAsState(initial = emptyList())
var searchQuery by remember { mutableStateOf("") }
// 🔍 Filtrage
val filteredDvds = dvds.filter { dvd ->
val query = searchQuery.lowercase()
dvd.titre.orEmpty().lowercase().contains(query) ||
dvd.realisateur.orEmpty().lowercase().contains(query) ||
dvd.genre.orEmpty().lowercase().contains(query) ||
dvd.annee.orEmpty().lowercase().contains(query)
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(8.dp)
) {
Spacer(modifier = Modifier.height(15.dp))
var sortType by remember { mutableStateOf(SortType.TITLE_ASC) }
Text(
"Votre collection",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(bottom = 8.dp)
)
val filteredAndSortedDvds = when (sortType) {
SortType.TITLE_ASC ->
filteredDvds.sortedBy { it.titre.orEmpty().lowercase() }
OutlinedTextField(
value = searchQuery,
onValueChange = { searchQuery = it },
label = { Text("Rechercher un DVD") },
SortType.TITLE_DESC ->
filteredDvds.sortedByDescending { it.titre.orEmpty() }
SortType.DIRECTOR_ASC ->
filteredDvds.sortedBy { it.realisateur.orEmpty() }
SortType.DIRECTOR_DESC ->
filteredDvds.sortedByDescending { it.realisateur.orEmpty() }
SortType.YEAR_ASC ->
filteredDvds.sortedBy { it.annee.orEmpty() }
SortType.YEAR_DESC ->
filteredDvds.sortedByDescending { it.annee.orEmpty() }
}
// 🔍 Filtrage
Scaffold(
floatingActionButtonPosition = FabPosition.Center,
floatingActionButton = {
ExtendedFloatingActionButton(
text = { Text("Ajouter") },
icon = { Text("+") },
onClick = {
context.startActivity(
Intent(context, AjoutDvdActivity::class.java)
)
}
)
}
) { padding ->
Column(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp),
singleLine = true
.fillMaxSize()
.padding(padding)
.padding(12.dp)
) {
TopBar()
SearchBar(searchQuery) { searchQuery = it }
Spacer(modifier = Modifier.height(8.dp))
SortChip(
currentSort = sortType,
onSortSelected = { sortType = it }
)
Spacer(modifier = Modifier.height(8.dp))
DvdList(filteredAndSortedDvds)
}
}
}
@Composable
fun TopBar() {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = "Votre Vidéothèque",
fontSize = 22.sp,
fontWeight = FontWeight.Bold
)
if (filteredDvds.isEmpty()) {
Box(
modifier = Modifier.weight(1f),
contentAlignment = Alignment.Center
// Row {
// Text("ⓘ", fontSize = 20.sp)
// }
}
}
@Composable
fun SearchBar(
value: String,
onValueChange: (String) -> Unit
) {
OutlinedTextField(
value = value,
onValueChange = onValueChange,
placeholder = { Text("Chercher votre film (Par: titre, réal, etc)") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
shape = RoundedCornerShape(50),
colors = TextFieldDefaults.colors(
focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
)
)
}
@Composable
fun SortChip(
currentSort: SortType,
onSortSelected: (SortType) -> Unit
) {
var expanded by remember { mutableStateOf(false) }
Card(
modifier = Modifier.clickable { expanded = true },
shape = RoundedCornerShape(50),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
) {
Text(
text = "${currentSort.label}",
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
fontSize = 14.sp
)
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
SortType.values().forEach { sort ->
DropdownMenuItem(
text = { Text(sort.label) },
onClick = {
expanded = false
onSortSelected(sort)
}
)
}
}
}
@Composable
fun DvdList(
dvds: List<Dvd>
) {
LazyColumn {
items(dvds, key = { it.id }) { dvd ->
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 6.dp),
shape = RoundedCornerShape(16.dp)
) {
Text("Aucun DVD correspondant")
}
} else {
LazyColumn(modifier = Modifier.weight(1f)) {
items(filteredDvds, key = { it.id }) { dvd ->
Column(modifier = Modifier.padding(8.dp)) {
Text(dvd.titre.orEmpty(), fontWeight = FontWeight.Bold)
Text("Réalisateur : ${dvd.realisateur.orEmpty()}")
Text("Année : ${dvd.annee.orEmpty()}")
Text("Genre : ${dvd.genre.orEmpty()}")
Divider()
Row(
modifier = Modifier.padding(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
// 📀 Affiche (image fictive si pas encore stockée)
Box(
modifier = Modifier
.height(90.dp)
.width(60.dp)
.background(
MaterialTheme.colorScheme.surfaceVariant,
RoundedCornerShape(8.dp)
)
)
Spacer(modifier = Modifier.width(12.dp))
Column {
Text(
dvd.titre.orEmpty().uppercase(),
fontWeight = FontWeight.SemiBold,
fontSize = 16.sp,
color = Color(0xFFFFA405)
)
Spacer(modifier = Modifier.height(4.dp))
Text(
"Réalisateur: ${dvd.realisateur.orEmpty().uppercase()}",
fontSize = 13.sp,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
"Année: ${dvd.annee.orEmpty()}",
fontSize = 13.sp,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
"Genre: ${dvd.genre.orEmpty().uppercase()}",
fontSize = 13.sp,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
}
}
Row(modifier = Modifier.fillMaxWidth()){
MyButton("+ Ajouter") {
context.startActivity(
Intent(
context,
AjoutDvdActivity::class.java
)
)
}
MyButton("- Supprimer") {
context.startActivity(
(Intent(
context,
SupprDvdActivity::class.java
))
)
}
}
Spacer(modifier = Modifier.height(16.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
MyButton("Quitter") { onQuit() }
}
}
}

View File

@@ -8,6 +8,7 @@ espressoCore = "3.7.0"
lifecycleRuntimeKtx = "2.10.0"
activityCompose = "1.12.1"
composeBom = "2024.09.00"
uiGraphics = "1.10.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -24,6 +25,7 @@ androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "u
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "uiGraphics" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }