Menyesuaikan Note Card pada Catatan berbintang, arsip, dan sampah

This commit is contained in:
202310715297 RAIHAN ARIQ MUZAKKI 2025-12-24 21:09:37 +07:00
parent 9d6ba5d63d
commit 2e3cb39244
5 changed files with 121 additions and 33 deletions

View File

@ -20,7 +20,8 @@ data class SerializableNote(
val id: String, val id: String,
val categoryId: String, val categoryId: String,
val title: String, val title: String,
val content: String, val description: String = "",
val content: String = "",
val timestamp: Long, val timestamp: Long,
val isArchived: Boolean, val isArchived: Boolean,
val isDeleted: Boolean, val isDeleted: Boolean,
@ -35,7 +36,7 @@ fun Category.toSerializable() = SerializableCategory(
gradientEnd = gradientEnd, gradientEnd = gradientEnd,
timestamp = timestamp, timestamp = timestamp,
isDeleted = isDeleted, isDeleted = isDeleted,
isPinned = isPinned // NEW: Tambahkan ini isPinned = isPinned
) )
fun SerializableCategory.toCategory() = Category( fun SerializableCategory.toCategory() = Category(
@ -45,13 +46,14 @@ fun SerializableCategory.toCategory() = Category(
gradientEnd = gradientEnd, gradientEnd = gradientEnd,
timestamp = timestamp, timestamp = timestamp,
isDeleted = isDeleted, isDeleted = isDeleted,
isPinned = isPinned // NEW: Tambahkan ini isPinned = isPinned
) )
fun Note.toSerializable() = SerializableNote( fun Note.toSerializable() = SerializableNote(
id = id, id = id,
categoryId = categoryId, categoryId = categoryId,
title = title, title = title,
description = description,
content = content, content = content,
timestamp = timestamp, timestamp = timestamp,
isArchived = isArchived, isArchived = isArchived,
@ -63,6 +65,7 @@ fun SerializableNote.toNote() = Note(
id = id, id = id,
categoryId = categoryId, categoryId = categoryId,
title = title, title = title,
description = description,
content = content, content = content,
timestamp = timestamp, timestamp = timestamp,
isArchived = isArchived, isArchived = isArchived,

View File

@ -25,6 +25,24 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.notesai.data.model.Note import com.example.notesai.data.model.Note
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
// Helper function untuk extract plain text dari AnnotatedString JSON
private fun extractPlainText(jsonContent: String): String {
return try {
if (jsonContent.trim().startsWith("{")) {
val jsonElement = Json.parseToJsonElement(jsonContent)
val jsonObject = jsonElement.jsonObject
jsonObject["text"]?.jsonPrimitive?.content ?: ""
} else {
jsonContent
}
} catch (e: Exception) {
jsonContent
}
}
@Composable @Composable
fun ArchiveNoteCard( fun ArchiveNoteCard(
@ -33,6 +51,12 @@ fun ArchiveNoteCard(
onRestore: () -> Unit, onRestore: () -> Unit,
onDelete: () -> Unit onDelete: () -> Unit
) { ) {
val displayContent = if (note.description.isNotEmpty()) {
note.description
} else {
extractPlainText(note.content)
}
Card( Card(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(16.dp), shape = RoundedCornerShape(16.dp),
@ -62,10 +86,10 @@ fun ArchiveNoteCard(
} }
} }
if (note.content.isNotEmpty()) { if (displayContent.isNotEmpty()) {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
note.content, displayContent,
maxLines = 2, maxLines = 2,
color = Color(0xFF94A3B8), color = Color(0xFF94A3B8),
style = MaterialTheme.typography.bodyMedium style = MaterialTheme.typography.bodyMedium

View File

@ -146,14 +146,23 @@ fun EditableFullScreenNoteView(
Icon( Icon(
if (note.isPinned) Icons.Filled.Star if (note.isPinned) Icons.Filled.Star
else Icons.Outlined.StarBorder, else Icons.Outlined.StarBorder,
null contentDescription = null,
tint = if (note.isPinned) Color(0xFFFFB300) else MaterialTheme.colorScheme.onSurface
) )
} }
IconButton(onClick = onArchive) { IconButton(onClick = onArchive) {
Icon(Icons.Default.Archive, null) Icon(
Icons.Default.Archive,
contentDescription = null,
tint = Color(0xFF4CAF50)
)
} }
IconButton(onClick = onDelete) { IconButton(onClick = onDelete) {
Icon(Icons.Default.Delete, null) Icon(
Icons.Default.Delete,
contentDescription = null,
tint = Color(0xFFF44336)
)
} }
} }
) )

View File

@ -29,6 +29,27 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.notesai.data.model.Note import com.example.notesai.data.model.Note
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
// Helper function untuk extract plain text dari AnnotatedString JSON
private fun extractPlainText(jsonContent: String): String {
return try {
if (jsonContent.trim().startsWith("{")) {
val jsonElement = Json.parseToJsonElement(jsonContent)
val jsonObject = jsonElement.jsonObject
// Extract field "text" yang berisi plain text content
jsonObject["text"]?.jsonPrimitive?.content ?: ""
} else {
jsonContent
}
} catch (e: Exception) {
// Jika parsing gagal, coba tampilkan content mentah
jsonContent
}
}
@Composable @Composable
fun StarredNoteCard( fun StarredNoteCard(
@ -37,8 +58,15 @@ fun StarredNoteCard(
onClick: () -> Unit, onClick: () -> Unit,
onUnpin: () -> Unit onUnpin: () -> Unit
) { ) {
// Gunakan description jika ada, jika tidak extract dari content JSON
val displayContent = if (note.description.isNotEmpty()) {
note.description
} else {
extractPlainText(note.content)
}
Card( Card(
modifier = Modifier.Companion modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable(onClick = onClick), .clickable(onClick = onClick),
shape = RoundedCornerShape(16.dp), shape = RoundedCornerShape(16.dp),
@ -47,31 +75,31 @@ fun StarredNoteCard(
), ),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) { ) {
Column(modifier = Modifier.Companion.padding(16.dp)) { Column(modifier = Modifier.padding(16.dp)) {
Row( Row(
modifier = Modifier.Companion.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.Companion.Top verticalAlignment = Alignment.Top
) { ) {
Column(modifier = Modifier.Companion.weight(1f)) { Column(modifier = Modifier.weight(1f)) {
Row( Row(
verticalAlignment = Alignment.Companion.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Icon( Icon(
Icons.Default.Star, Icons.Default.Star,
contentDescription = null, contentDescription = null,
tint = Color(0xFFFBBF24), tint = Color(0xFFFBBF24),
modifier = Modifier.Companion.size(16.dp) modifier = Modifier.size(16.dp)
) )
Spacer(modifier = Modifier.Companion.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(
note.title, note.title,
fontWeight = FontWeight.Companion.Bold, fontWeight = FontWeight.Bold,
color = Color.Companion.White, color = Color.White,
style = MaterialTheme.typography.titleMedium style = MaterialTheme.typography.titleMedium
) )
} }
Spacer(modifier = Modifier.Companion.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
Text( Text(
categoryName, categoryName,
color = Color(0xFF64748B), color = Color(0xFF64748B),
@ -80,19 +108,19 @@ fun StarredNoteCard(
} }
} }
if (note.content.isNotEmpty()) { if (displayContent.isNotEmpty()) {
Spacer(modifier = Modifier.Companion.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
note.content, displayContent,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Companion.Ellipsis, overflow = TextOverflow.Ellipsis,
color = Color(0xFF94A3B8), color = Color(0xFF94A3B8),
style = MaterialTheme.typography.bodyMedium style = MaterialTheme.typography.bodyMedium
) )
} }
Row( Row(
modifier = Modifier.Companion modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 12.dp), .padding(top = 12.dp),
horizontalArrangement = Arrangement.End horizontalArrangement = Arrangement.End
@ -101,29 +129,29 @@ fun StarredNoteCard(
Icon( Icon(
Icons.Default.Info, Icons.Default.Info,
contentDescription = null, contentDescription = null,
modifier = Modifier.Companion.size(18.dp), modifier = Modifier.size(18.dp),
tint = Color(0xFF6366F1) tint = Color(0xFF6366F1)
) )
Spacer(modifier = Modifier.Companion.width(4.dp)) Spacer(modifier = Modifier.width(4.dp))
Text( Text(
"Lihat Detail", "Lihat Detail",
color = Color(0xFF6366F1), color = Color(0xFF6366F1),
fontWeight = FontWeight.Companion.Bold fontWeight = FontWeight.Bold
) )
} }
Spacer(modifier = Modifier.Companion.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
TextButton(onClick = onUnpin) { TextButton(onClick = onUnpin) {
Icon( Icon(
Icons.Outlined.StarBorder, Icons.Outlined.StarBorder,
contentDescription = null, contentDescription = null,
modifier = Modifier.Companion.size(18.dp), modifier = Modifier.size(18.dp),
tint = Color(0xFFFBBF24) tint = Color(0xFFFBBF24)
) )
Spacer(modifier = Modifier.Companion.width(4.dp)) Spacer(modifier = Modifier.width(4.dp))
Text( Text(
"Hapus Bintang", "Hapus Bintang",
color = Color(0xFFFBBF24), color = Color(0xFFFBBF24),
fontWeight = FontWeight.Companion.Bold fontWeight = FontWeight.Bold
) )
} }
} }

View File

@ -25,6 +25,24 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.notesai.data.model.Note import com.example.notesai.data.model.Note
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
// Helper function untuk extract plain text dari AnnotatedString JSON
private fun extractPlainText(jsonContent: String): String {
return try {
if (jsonContent.trim().startsWith("{")) {
val jsonElement = Json.parseToJsonElement(jsonContent)
val jsonObject = jsonElement.jsonObject
jsonObject["text"]?.jsonPrimitive?.content ?: ""
} else {
jsonContent
}
} catch (e: Exception) {
jsonContent
}
}
@Composable @Composable
fun TrashNoteCard( fun TrashNoteCard(
@ -33,6 +51,12 @@ fun TrashNoteCard(
onRestore: () -> Unit, onRestore: () -> Unit,
onDeletePermanent: () -> Unit onDeletePermanent: () -> Unit
) { ) {
val displayContent = if (note.description.isNotEmpty()) {
note.description
} else {
extractPlainText(note.content)
}
Card( Card(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(16.dp), shape = RoundedCornerShape(16.dp),
@ -62,10 +86,10 @@ fun TrashNoteCard(
} }
} }
if (note.content.isNotEmpty()) { if (displayContent.isNotEmpty()) {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
note.content, displayContent,
maxLines = 2, maxLines = 2,
color = Color(0xFF94A3B8), color = Color(0xFF94A3B8),
style = MaterialTheme.typography.bodyMedium style = MaterialTheme.typography.bodyMedium