Merge remote-tracking branch 'origin/main'
commit
a616a0b9f1
|
@ -1,228 +1,122 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.grid.GridCells
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.material.Button
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.material.icons.filled.Search
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun glossaryDetailedPage(glossary: List<Word>, onBackClick: () -> Unit) {
|
fun glossaryDetailedPage(glossary: List<Word>, onBackClick: () -> Unit) {
|
||||||
var searchQuery by remember { mutableStateOf("") }
|
|
||||||
var sortOption by remember { mutableStateOf("Nom ↑") }
|
|
||||||
|
|
||||||
var filteredGlossary by remember { mutableStateOf(glossary) }
|
|
||||||
|
|
||||||
val menuExpanded = remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
// Sort the glossary according to the selected option
|
|
||||||
val sortedGlossaire = remember(glossary, sortOption) {
|
|
||||||
val glossaireCopy = glossary.toMutableList()
|
|
||||||
|
|
||||||
when (sortOption) {
|
|
||||||
"Nom ↑" -> glossaireCopy.sortBy { it.name }
|
|
||||||
"Nom ↓" -> glossaireCopy.sortByDescending { it.name }
|
|
||||||
"Contexte ↑" -> glossaireCopy.sortBy { it.mainContext }
|
|
||||||
"Contexte ↓" -> glossaireCopy.sortByDescending { it.mainContext }
|
|
||||||
}
|
|
||||||
|
|
||||||
glossaireCopy
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the filtered glossary when the search query changes
|
|
||||||
filteredGlossary = if (searchQuery.isNotEmpty()) {
|
|
||||||
glossary.filter { mot ->
|
|
||||||
mot.name.contains(searchQuery, ignoreCase = true) ||
|
|
||||||
mot.description.contains(searchQuery, ignoreCase = true) ||
|
|
||||||
mot.mainContext.contains(searchQuery, ignoreCase = true) ||
|
|
||||||
mot.secondaryContext.contains(searchQuery, ignoreCase = true) ||
|
|
||||||
mot.relatedTo.contains(searchQuery, ignoreCase = true) ||
|
|
||||||
mot.synonymous.contains(searchQuery, ignoreCase = true) ||
|
|
||||||
mot.antonym.contains(searchQuery, ignoreCase = true)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sortedGlossaire
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
verticalArrangement = Arrangement.Top, // Align content at the top
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
Text(text = "Détail du glossaire", style = MaterialTheme.typography.h3)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
glossaryTable(glossary = glossary)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = { onBackClick() },
|
||||||
|
colors = androidx.compose.material.ButtonDefaults.buttonColors(
|
||||||
backgroundColor = customRedColor,
|
backgroundColor = customRedColor,
|
||||||
title = { Text("Glossaire", color = Color.White) },
|
contentColor = Color.White
|
||||||
navigationIcon = {
|
)
|
||||||
IconButton(onClick = onBackClick) {
|
) {
|
||||||
Icon(imageVector = Icons.Default.ArrowBack, contentDescription = "Retour", tint = Color.White)
|
Icon(imageVector = Icons.Default.ArrowBack, contentDescription = null)
|
||||||
|
Text("Retour")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Faire un tableau qui affiche les mots et leur définition
|
||||||
|
@Composable
|
||||||
|
fun glossaryTable(glossary: List<Word>) {
|
||||||
|
val listState = rememberLazyListState()
|
||||||
|
LazyColumn(state = listState, modifier = Modifier.padding(16.dp)) {
|
||||||
|
item {
|
||||||
|
headerRow()
|
||||||
|
}
|
||||||
|
items(glossary) { word ->
|
||||||
|
glossaryDataRow(word)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun headerRow() {
|
||||||
|
val headers = listOf(
|
||||||
|
"Mot",
|
||||||
|
"Définition",
|
||||||
|
"Contexte principal",
|
||||||
|
"Contexte secondaire",
|
||||||
|
"Mot lié",
|
||||||
|
"Synonyme",
|
||||||
|
"Antonyme"
|
||||||
)
|
)
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(16.dp),
|
.background(customRedColor)
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
.border(1.dp, Color.Black),
|
||||||
) {
|
verticalAlignment = Alignment.CenterVertically
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.border(1.dp, customRedColor, RoundedCornerShape(4.dp))
|
|
||||||
.padding(8.dp)
|
|
||||||
.clickable {
|
|
||||||
menuExpanded.value = !menuExpanded.value
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
|
headers.forEach { header ->
|
||||||
Text(
|
Text(
|
||||||
text = "Trier par: $sortOption",
|
text = header,
|
||||||
color = Color.Black
|
fontWeight = FontWeight.Bold,
|
||||||
|
modifier = Modifier.weight(1f).padding(8.dp),
|
||||||
|
color = Color.White
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = menuExpanded.value,
|
|
||||||
onDismissRequest = {
|
|
||||||
menuExpanded.value = false
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
DropdownMenuItem(onClick = {
|
|
||||||
sortOption = "Nom ↑"
|
|
||||||
menuExpanded.value = false
|
|
||||||
}) {
|
|
||||||
Text("Nom ↑")
|
|
||||||
}
|
|
||||||
|
|
||||||
DropdownMenuItem(onClick = {
|
|
||||||
sortOption = "Nom ↓"
|
|
||||||
menuExpanded.value = false
|
|
||||||
}) {
|
|
||||||
Text("Nom ↓")
|
|
||||||
}
|
|
||||||
|
|
||||||
DropdownMenuItem(onClick = {
|
|
||||||
sortOption = "Contexte ↑"
|
|
||||||
menuExpanded.value = false
|
|
||||||
}) {
|
|
||||||
Text("Contexte ↑")
|
|
||||||
}
|
|
||||||
|
|
||||||
DropdownMenuItem(onClick = {
|
|
||||||
sortOption = "Contexte ↓"
|
|
||||||
menuExpanded.value = false
|
|
||||||
}) {
|
|
||||||
Text("Contexte ↓")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = searchQuery,
|
|
||||||
onValueChange = {
|
|
||||||
searchQuery = it
|
|
||||||
},
|
|
||||||
label = { Text("Rechercher dans le glossaire") },
|
|
||||||
keyboardOptions = KeyboardOptions.Default.copy(
|
|
||||||
imeAction = ImeAction.Search,
|
|
||||||
keyboardType = KeyboardType.Text
|
|
||||||
),
|
|
||||||
singleLine = true, // Single line text field
|
|
||||||
leadingIcon = {
|
|
||||||
Icon(imageVector = Icons.Default.Search, contentDescription = null)
|
|
||||||
},
|
|
||||||
colors = TextFieldDefaults.outlinedTextFieldColors(
|
|
||||||
focusedBorderColor = customRedColor,
|
|
||||||
cursorColor = customRedColor,
|
|
||||||
focusedLabelColor = customRedColor,
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(16.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
LazyVerticalGrid(
|
|
||||||
columns = GridCells.Fixed(2),
|
|
||||||
contentPadding = PaddingValues(16.dp),
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
) {
|
|
||||||
items(filteredGlossary) { mot ->
|
|
||||||
glossaryCard(mot, onDeleteClick = { wordToDelete ->
|
|
||||||
deleteWordOfGlossary(wordToDelete)
|
|
||||||
// Display the updated glossary
|
|
||||||
filteredGlossary = loadDatasFromFile()
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun glossaryCard(word: Word, onDeleteClick: (Word) -> Unit) {
|
fun CellContent(text: String, modifier: Modifier = Modifier) {
|
||||||
Card(
|
Text(
|
||||||
modifier = Modifier
|
text = text,
|
||||||
.fillMaxWidth()
|
modifier = modifier
|
||||||
.padding(8.dp),
|
|
||||||
|
|
||||||
elevation = 8.dp
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(16.dp)
|
|
||||||
) {
|
|
||||||
Text(text = word.name, style = MaterialTheme.typography.h6)
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
Text(text = "Description: ${word.description}")
|
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
|
||||||
Text(text = "Contexte principal: ${word.mainContext}")
|
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
|
||||||
Text(text = "Contexte 2: ${word.secondaryContext}")
|
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
|
||||||
Text(text = "Lié à: ${word.relatedTo}")
|
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
|
||||||
Text(text = "Synonyme: ${word.synonymous}")
|
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
|
||||||
Text(text = "Antonyme: ${word.antonym}")
|
|
||||||
|
|
||||||
// Add a delete button to delete the word
|
|
||||||
IconButton(
|
|
||||||
onClick = { onDeleteClick(word) },
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.End)
|
|
||||||
.padding(top = 8.dp)
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.Delete,
|
|
||||||
contentDescription = "Supprimer",
|
|
||||||
tint = customRedColor
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun glossaryDataRow(word: Word) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(Color.White)
|
||||||
|
.border(1.dp, Color.Black), // Ajouter une bordure à chaque ligne
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
val modifier = Modifier.weight(1f).padding(8.dp)
|
||||||
|
// Contenu de chaque cellule
|
||||||
|
CellContent(word.name, modifier)
|
||||||
|
CellContent(word.description, modifier)
|
||||||
|
CellContent(word.mainContext, modifier)
|
||||||
|
CellContent(word.secondaryContext, modifier)
|
||||||
|
CellContent(word.relatedTo, modifier)
|
||||||
|
CellContent(word.synonymous, modifier)
|
||||||
|
CellContent(word.antonym, modifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun deleteWordOfGlossary(word: Word) {
|
|
||||||
val wordsList = loadDatasFromFile().toMutableList()
|
|
||||||
|
|
||||||
// Delete the word from the list
|
|
||||||
wordsList.remove(word)
|
|
||||||
|
|
||||||
// Save the updated list to the file
|
|
||||||
saveDatasInFile(wordsList)
|
|
||||||
|
|
||||||
println("Mot supprimé avec succès : ${word.name}")
|
|
||||||
}
|
|
Loading…
Reference in New Issue