Compare commits

...

2 Commits

2 changed files with 17 additions and 28 deletions

View File

@ -89,6 +89,7 @@
* **Search di kategori** - Cari catatan berdasarkan judul & isi (case-insensitive) * **Search di kategori** - Cari catatan berdasarkan judul & isi (case-insensitive)
* **Search empty state** - Tampilkan pesan "Tidak ada hasil" saat search kosong * **Search empty state** - Tampilkan pesan "Tidak ada hasil" saat search kosong
* **Gradle optimization** - Cleanup dependencies yang tidak diperlukan * **Gradle optimization** - Cleanup dependencies yang tidak diperlukan
* **Hilangkan Fitur Tahan Untuk Hapus**
--- ---

View File

@ -52,6 +52,7 @@ import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.ContentCopy
import androidx.compose.material.icons.outlined.StarBorder import androidx.compose.material.icons.outlined.StarBorder
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.zIndex import androidx.compose.ui.zIndex
@ -114,7 +115,7 @@ class MainActivity : ComponentActivity() {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun NotesApp() { fun NotesApp() {
val context = androidx.compose.ui.platform.LocalContext.current val context = LocalContext.current
val dataStoreManager = remember { DataStoreManager(context) } val dataStoreManager = remember { DataStoreManager(context) }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@ -155,7 +156,7 @@ fun NotesApp() {
// Simpan categories dengan debounce // Simpan categories dengan debounce
LaunchedEffect(categories.size) { LaunchedEffect(categories.size) {
if (categories.isNotEmpty()) { if (categories.isNotEmpty()) {
kotlinx.coroutines.delay(500) delay(500)
try { try {
dataStoreManager.saveCategories(categories) dataStoreManager.saveCategories(categories)
} catch (e: Exception) { } catch (e: Exception) {
@ -167,7 +168,7 @@ fun NotesApp() {
// Simpan notes dengan debounce // Simpan notes dengan debounce
LaunchedEffect(notes.size) { LaunchedEffect(notes.size) {
if (notes.isNotEmpty()) { if (notes.isNotEmpty()) {
kotlinx.coroutines.delay(500) delay(500)
try { try {
dataStoreManager.saveNotes(notes) dataStoreManager.saveNotes(notes)
} catch (e: Exception) { } catch (e: Exception) {
@ -311,19 +312,13 @@ fun NotesApp() {
fullScreenNote = note fullScreenNote = note
showFullScreenNote = true showFullScreenNote = true
}, },
onNoteLongClick = { note ->
notes = notes.map {
if (it.id == note.id) it.copy(isArchived = true)
else it
}
},
onPinToggle = { note -> onPinToggle = { note ->
notes = notes.map { notes = notes.map {
if (it.id == note.id) it.copy(isPinned = !it.isPinned) if (it.id == note.id) it.copy(isPinned = !it.isPinned)
else it else it
} }
}, },
onCategoryLongClick = { category -> onCategoryDelete = { category ->
// Delete kategori dan semua catatan di dalamnya // Delete kategori dan semua catatan di dalamnya
categories = categories.filter { it.id != category.id } categories = categories.filter { it.id != category.id }
notes = notes.filter { it.categoryId != category.id } notes = notes.filter { it.categoryId != category.id }
@ -824,9 +819,8 @@ fun MainScreen(
searchQuery: String, searchQuery: String,
onCategoryClick: (Category) -> Unit, onCategoryClick: (Category) -> Unit,
onNoteClick: (Note) -> Unit, onNoteClick: (Note) -> Unit,
onNoteLongClick: (Note) -> Unit,
onPinToggle: (Note) -> Unit, onPinToggle: (Note) -> Unit,
onCategoryLongClick: (Category) -> Unit onCategoryDelete: (Category) -> Unit
) { ) {
Column(modifier = Modifier.fillMaxSize()) { Column(modifier = Modifier.fillMaxSize()) {
if (selectedCategory == null) { if (selectedCategory == null) {
@ -866,10 +860,8 @@ fun MainScreen(
category = category, category = category,
noteCount = notes.count { it.categoryId == category.id && !it.isDeleted && !it.isArchived }, noteCount = notes.count { it.categoryId == category.id && !it.isDeleted && !it.isArchived },
onClick = { onCategoryClick(category) }, onClick = { onCategoryClick(category) },
onLongClick = { onCategoryLongClick(category) },
onDelete = { onDelete = {
// Delete kategori dan semua catatan di dalamnya onCategoryDelete(category)
onCategoryLongClick(category)
} }
) )
} }
@ -906,8 +898,7 @@ fun MainScreen(
NoteCard( NoteCard(
note = note, note = note,
onClick = { onNoteClick(note) }, onClick = { onNoteClick(note) },
onLongClick = { onNoteLongClick(note) }, onPinClick = { onPinToggle(note) },
onPinClick = { onPinToggle(note) }
) )
} }
} }
@ -922,7 +913,6 @@ fun CategoryCard(
category: Category, category: Category,
noteCount: Int, noteCount: Int,
onClick: () -> Unit, onClick: () -> Unit,
onLongClick: () -> Unit,
onDelete: () -> Unit = {} onDelete: () -> Unit = {}
) { ) {
var showDeleteConfirm by remember { mutableStateOf(false) } var showDeleteConfirm by remember { mutableStateOf(false) }
@ -931,9 +921,9 @@ fun CategoryCard(
if (showDeleteConfirm) { if (showDeleteConfirm) {
AlertDialog( AlertDialog(
onDismissRequest = { showDeleteConfirm = false }, onDismissRequest = { showDeleteConfirm = false },
title = { Text("Hapus Kategori?") }, title = { Text("Hapus Kategori?", color = Color.White) },
text = { text = {
Text("Kategori '$${category.name}' dan semua catatan di dalamnya akan dihapus. Tindakan ini tidak dapat dibatalkan.") Text("Kategori '${category.name}' dan semua catatan di dalamnya akan dihapus. Tindakan ini tidak dapat dibatalkan.", color = Color.White)
}, },
confirmButton = { confirmButton = {
Button( Button(
@ -957,17 +947,15 @@ fun CategoryCard(
) { ) {
Text("Batal", color = Color.White) Text("Batal", color = Color.White)
} }
} },
containerColor = Color(0xFF1E293B)
) )
} }
Card( Card(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.combinedClickable( .clickable(onClick = onClick),
onClick = onClick,
onLongClick = onLongClick
),
shape = RoundedCornerShape(20.dp), shape = RoundedCornerShape(20.dp),
colors = CardDefaults.cardColors(containerColor = Color.Transparent), colors = CardDefaults.cardColors(containerColor = Color.Transparent),
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp) elevation = CardDefaults.cardElevation(defaultElevation = 0.dp)
@ -1009,7 +997,9 @@ fun CategoryCard(
// Delete button di top-right corner // Delete button di top-right corner
IconButton( IconButton(
onClick = { showDeleteConfirm = true }, onClick = {
showDeleteConfirm = true
},
modifier = Modifier modifier = Modifier
.align(Alignment.TopEnd) .align(Alignment.TopEnd)
.size(40.dp) .size(40.dp)
@ -1030,7 +1020,6 @@ fun CategoryCard(
fun NoteCard( fun NoteCard(
note: Note, note: Note,
onClick: () -> Unit, onClick: () -> Unit,
onLongClick: () -> Unit,
onPinClick: () -> Unit onPinClick: () -> Unit
) { ) {
val dateFormat = SimpleDateFormat("dd MMM, HH:mm", Locale("id", "ID")) val dateFormat = SimpleDateFormat("dd MMM, HH:mm", Locale("id", "ID"))
@ -1040,7 +1029,6 @@ fun NoteCard(
.fillMaxWidth() .fillMaxWidth()
.combinedClickable( .combinedClickable(
onClick = onClick, onClick = onClick,
onLongClick = onLongClick
), ),
shape = RoundedCornerShape(16.dp), shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors( colors = CardDefaults.cardColors(