Mengganti Preview deskripsi Note Card dan Note Dialog

This commit is contained in:
202310715082 FAZRI ABDURRAHMAN 2025-12-17 21:35:13 +07:00
parent de163a09f8
commit 900bf8b7ff
7 changed files with 86 additions and 39 deletions

View File

@ -144,7 +144,7 @@
## **Planned Features (v1.1.0)**
* Backup & restore data
* Tags untuk catatan
* Mengganti Preview deskripsi Note Card dan Note Dialog (ok)
* Rich text editor
* Dark theme toggle
* Multi-language support

View File

@ -445,13 +445,13 @@ fun NotesApp() {
showNoteDialog = false
editingNote = null
},
onSave = { title, content ->
onSave = { title, description ->
if (editingNote != null) {
notes = notes.map {
if (it.id == editingNote!!.id)
it.copy(
title = title,
content = content,
description = description,
timestamp = System.currentTimeMillis()
)
else it
@ -460,11 +460,14 @@ fun NotesApp() {
notes = notes + Note(
categoryId = selectedCategory!!.id,
title = title,
content = content
description = description,
content = "" // Content kosong, akan diisi di EditableFullScreenNoteView
)
}
showNoteDialog = false
editingNote = null
showNoteDialog = false
editingNote = null
},
onDelete = if (editingNote != null) {
{

View File

@ -28,7 +28,8 @@ data class SerializableCategory(
val name: String,
val gradientStart: Long,
val gradientEnd: Long,
val timestamp: Long
val timestamp: Long,
val isDeleted: Boolean = false // Support untuk soft delete
)
@Serializable
@ -36,11 +37,12 @@ data class SerializableNote(
val id: String,
val categoryId: String,
val title: String,
val content: String,
val description: String = "", // Field baru untuk v1.1.0
val content: String = "",
val timestamp: Long,
val isArchived: Boolean,
val isDeleted: Boolean,
val isPinned: Boolean
val isArchived: Boolean = false,
val isDeleted: Boolean = false,
val isPinned: Boolean = false
)
class DataStoreManager(private val context: Context) {
@ -50,7 +52,7 @@ class DataStoreManager(private val context: Context) {
}
private val json = Json {
ignoreUnknownKeys = true
ignoreUnknownKeys = true // Penting untuk backward compatibility
encodeDefaults = true
}
@ -66,9 +68,17 @@ class DataStoreManager(private val context: Context) {
val jsonString = preferences[CATEGORIES_KEY] ?: "[]"
try {
json.decodeFromString<List<SerializableCategory>>(jsonString).map {
Category(it.id, it.name, it.gradientStart, it.gradientEnd, it.timestamp)
Category(
id = it.id,
name = it.name,
gradientStart = it.gradientStart,
gradientEnd = it.gradientEnd,
timestamp = it.timestamp,
isDeleted = it.isDeleted
)
}
} catch (e: Exception) {
e.printStackTrace()
emptyList()
}
}
@ -86,17 +96,19 @@ class DataStoreManager(private val context: Context) {
try {
json.decodeFromString<List<SerializableNote>>(jsonString).map {
Note(
it.id,
it.categoryId,
it.title,
it.content,
it.timestamp,
it.isArchived,
it.isDeleted,
it.isPinned
id = it.id,
categoryId = it.categoryId,
title = it.title,
description = it.description, // Support field baru
content = it.content,
timestamp = it.timestamp,
isPinned = it.isPinned,
isArchived = it.isArchived,
isDeleted = it.isDeleted
)
}
} catch (e: Exception) {
e.printStackTrace()
emptyList()
}
}
@ -105,7 +117,14 @@ class DataStoreManager(private val context: Context) {
try {
context.dataStore.edit { preferences ->
val serializable = categories.map {
SerializableCategory(it.id, it.name, it.gradientStart, it.gradientEnd, it.timestamp)
SerializableCategory(
id = it.id,
name = it.name,
gradientStart = it.gradientStart,
gradientEnd = it.gradientEnd,
timestamp = it.timestamp,
isDeleted = it.isDeleted
)
}
preferences[CATEGORIES_KEY] = json.encodeToString(serializable)
}
@ -118,7 +137,17 @@ class DataStoreManager(private val context: Context) {
try {
context.dataStore.edit { preferences ->
val serializable = notes.map {
SerializableNote(it.id, it.categoryId, it.title, it.content, it.timestamp, it.isArchived, it.isDeleted, it.isPinned)
SerializableNote(
id = it.id,
categoryId = it.categoryId,
title = it.title,
description = it.description, // Support field baru
content = it.content,
timestamp = it.timestamp,
isPinned = it.isPinned,
isArchived = it.isArchived,
isDeleted = it.isDeleted
)
}
preferences[NOTES_KEY] = json.encodeToString(serializable)
}

View File

@ -1,13 +1,14 @@
// File: data/model/Category.kt
package com.example.notesai.data.model
import kotlinx.serialization.Serializable
import java.util.UUID
@Serializable
data class Category(
val id: String = UUID.randomUUID().toString(),
val name: String,
val gradientStart: Long,
val gradientEnd: Long,
val timestamp: Long = System.currentTimeMillis(),
val isDeleted: Boolean = false // TAMBAHKAN INI
val isDeleted: Boolean = false // Support soft delete
)

View File

@ -1,15 +1,17 @@
// File: data/model/Note.kt
package com.example.notesai.data.model
import kotlinx.serialization.Serializable
import java.util.UUID
@Serializable
data class Note(
val id: String = UUID.randomUUID().toString(),
val categoryId: String,
val title: String,
val content: String,
val description: String = "", // Field baru untuk preview di NoteCard
val content: String = "", // Konten lengkap untuk EditableFullScreenNoteView
val timestamp: Long = System.currentTimeMillis(),
val isPinned: Boolean = false,
val isArchived: Boolean = false,
val isDeleted: Boolean = false,
val isPinned: Boolean = false
val isDeleted: Boolean = false
)

View File

@ -35,7 +35,7 @@ fun NoteDialog(
onDelete: (() -> Unit)?
) {
var title by remember { mutableStateOf(note?.title ?: "") }
var content by remember { mutableStateOf(note?.content ?: "") }
var description by remember { mutableStateOf(note?.description ?: "") }
AlertDialog(
onDismissRequest = onDismiss,
@ -69,13 +69,14 @@ fun NoteDialog(
Spacer(modifier = Modifier.height(12.dp))
OutlinedTextField(
value = content,
onValueChange = { content = it },
label = { Text("Isi Catatan", color = Color(0xFF94A3B8)) },
value = description,
onValueChange = { description = it },
label = { Text("Deskripsi", color = Color(0xFF94A3B8)) },
placeholder = { Text("Tambahkan deskripsi singkat...", color = Color(0xFF64748B)) },
modifier = Modifier
.fillMaxWidth()
.height(200.dp),
maxLines = 10,
.height(120.dp),
maxLines = 5,
colors = TextFieldDefaults.colors(
focusedTextColor = Color.White,
unfocusedTextColor = Color.White,
@ -98,7 +99,7 @@ fun NoteDialog(
Spacer(modifier = Modifier.width(8.dp))
}
Button(
onClick = { if (title.isNotBlank()) onSave(title, content) },
onClick = { if (title.isNotBlank()) onSave(title, description) },
enabled = title.isNotBlank(),
colors = ButtonDefaults.buttonColors(
containerColor = Color.Transparent

View File

@ -51,7 +51,7 @@ fun NoteCard(
.combinedClickable(onClick = onClick),
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(
containerColor = Constants.AppColors.SurfaceVariant // Lebih terang dari Surface
containerColor = Constants.AppColors.SurfaceVariant
),
elevation = CardDefaults.cardElevation(
defaultElevation = 2.dp
@ -94,19 +94,30 @@ fun NoteCard(
}
}
// Content Preview
if (note.content.isNotEmpty()) {
// Deskripsi Preview
if (note.description.isNotEmpty()) {
Spacer(modifier = Modifier.height(12.dp))
Text(
note.content,
note.description,
style = MaterialTheme.typography.bodyMedium,
maxLines = 4,
maxLines = 3,
overflow = TextOverflow.Ellipsis,
color = Constants.AppColors.OnSurfaceVariant,
lineHeight = 20.sp,
fontSize = 14.sp
)
} else {
// Tampilkan placeholder jika deskripsi kosong
Spacer(modifier = Modifier.height(12.dp))
Text(
"Tidak ada deskripsi",
style = MaterialTheme.typography.bodyMedium,
color = Constants.AppColors.OnSurfaceVariant.copy(alpha = 0.5f),
fontStyle = androidx.compose.ui.text.font.FontStyle.Italic,
fontSize = 14.sp
)
}
Spacer(modifier = Modifier.height(16.dp))