Penyesuaian Migrasi (import Library), Fix Bug Aplikasi Crash, Menambahkan Fitur edit dan hapus pada kategori

This commit is contained in:
202310715297 RAIHAN ARIQ MUZAKKI 2025-12-13 15:45:43 +07:00
parent 63b10a3e1c
commit 3f84068d72
20 changed files with 285 additions and 198 deletions

View File

@ -4,10 +4,10 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-12-12T17:42:15.072692700Z"> <DropdownSelection timestamp="2025-12-13T07:41:36.634314200Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\dendi\.android\avd\Medium_Phone.avd" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=RR8T103A6JZ" />
</handle> </handle>
</Target> </Target>
</DropdownSelection> </DropdownSelection>

View File

@ -1,5 +1,6 @@
package com.example.notesai package com.example.notesai
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
@ -11,12 +12,10 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.* import androidx.compose.material.icons.filled.*
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import java.util.UUID import java.util.UUID
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@ -31,37 +30,13 @@ import com.example.notesai.presentation.screens.ai.AIHelperScreen
import com.example.notesai.presentation.screens.archive.ArchiveScreen import com.example.notesai.presentation.screens.archive.ArchiveScreen
import com.example.notesai.presentation.screens.main.MainScreen import com.example.notesai.presentation.screens.main.MainScreen
import com.example.notesai.presentation.screens.note.EditableFullScreenNoteView import com.example.notesai.presentation.screens.note.EditableFullScreenNoteView
import com.example.notesai.presentation.screens.starred.components.StarredNotesScreen import com.example.notesai.presentation.screens.starred.StarredNotesScreen
import com.example.notesai.presentation.screens.trash.components.TrashScreen import com.example.notesai.presentation.screens.trash.TrashScreen
import com.example.notesai.data.model.Note
import com.example.notesai.data.model.Category
import com.example.notesai.util.updateWhere
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
// Data Classes
data class Category(
val id: String = UUID.randomUUID().toString(),
val name: String,
val gradientStart: Long,
val gradientEnd: Long,
val timestamp: Long = System.currentTimeMillis()
)
data class Note(
val id: String = UUID.randomUUID().toString(),
val categoryId: String,
val title: String,
val content: String,
val timestamp: Long = System.currentTimeMillis(),
val isArchived: Boolean = false,
val isDeleted: Boolean = false,
val isPinned: Boolean = false
)
data class ChatMessage(
val id: String = UUID.randomUUID().toString(),
val message: String,
val isUser: Boolean,
val timestamp: Long = System.currentTimeMillis()
)
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -300,6 +275,19 @@ fun NotesApp() {
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 }
selectedCategory = null selectedCategory = null
},
onCategoryEdit = { category, newName, newGradientStart, newGradientEnd ->
categories = categories.updateWhere(
predicate = { it.id == category.id },
transform = {
it.copy(
name = newName,
gradientStart = newGradientStart,
gradientEnd = newGradientEnd,
timestamp = System.currentTimeMillis()
)
}
)
} }
) )
"starred" -> StarredNotesScreen( "starred" -> StarredNotesScreen(

View File

@ -1,5 +1,5 @@
package com.example.notesai.config package com.example.notesai.config
object APIKey { object APIKey {
const val GEMINI_API_KEY = "MY_GEMINI_KEY" const val GEMINI_API_KEY = "AIzaSyBzC64RXsNtSERlts_FSd8HXKEpkLdT7-8"
} }

View File

@ -9,8 +9,8 @@ import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.emptyPreferences import androidx.datastore.preferences.core.emptyPreferences
import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore import androidx.datastore.preferences.preferencesDataStore
import com.example.notesai.Category import com.example.notesai.data.model.Note
import com.example.notesai.Note import com.example.notesai.data.model.Category
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map

View File

@ -1,9 +0,0 @@
// File: data/local/PreferencesKeys.kt
package com.example.notesai.data.local
import androidx.datastore.preferences.core.stringPreferencesKey
object PreferencesKeys {
val CATEGORIES_KEY = stringPreferencesKey("categories")
val NOTES_KEY = stringPreferencesKey("notes")
}

View File

@ -1,67 +0,0 @@
// File: data/model/SerializableModels.kt
package com.example.notesai.data.model
import android.annotation.SuppressLint
import kotlinx.serialization.Serializable
@SuppressLint("UnsafeOptInUsageError")
@Serializable
data class SerializableCategory(
val id: String,
val name: String,
val gradientStart: Long,
val gradientEnd: Long,
val timestamp: Long
)
@SuppressLint("UnsafeOptInUsageError")
@Serializable
data class SerializableNote(
val id: String,
val categoryId: String,
val title: String,
val content: String,
val timestamp: Long,
val isArchived: Boolean,
val isDeleted: Boolean,
val isPinned: Boolean
)
// Extension functions untuk konversi
fun Category.toSerializable() = SerializableCategory(
id = id,
name = name,
gradientStart = gradientStart,
gradientEnd = gradientEnd,
timestamp = timestamp
)
fun SerializableCategory.toCategory() = Category(
id = id,
name = name,
gradientStart = gradientStart,
gradientEnd = gradientEnd,
timestamp = timestamp
)
fun Note.toSerializable() = SerializableNote(
id = id,
categoryId = categoryId,
title = title,
content = content,
timestamp = timestamp,
isArchived = isArchived,
isDeleted = isDeleted,
isPinned = isPinned
)
fun SerializableNote.toNote() = Note(
id = id,
categoryId = categoryId,
title = title,
content = content,
timestamp = timestamp,
isArchived = isArchived,
isDeleted = isDeleted,
isPinned = isPinned
)

View File

@ -25,7 +25,7 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color 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.Note import com.example.notesai.data.model.Note
@Composable @Composable
fun NoteDialog( fun NoteDialog(

View File

@ -53,9 +53,9 @@ import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.notesai.Category import com.example.notesai.data.model.Note
import com.example.notesai.ChatMessage import com.example.notesai.data.model.ChatMessage
import com.example.notesai.Note import com.example.notesai.data.model.Category
import com.example.notesai.config.APIKey import com.example.notesai.config.APIKey
import com.example.notesai.presentation.screens.ai.components.ChatBubble import com.example.notesai.presentation.screens.ai.components.ChatBubble
import com.example.notesai.presentation.screens.ai.components.CompactStatItem import com.example.notesai.presentation.screens.ai.components.CompactStatItem

View File

@ -23,7 +23,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.example.notesai.ChatMessage import com.example.notesai.data.model.ChatMessage
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale

View File

@ -8,8 +8,8 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Archive import androidx.compose.material.icons.filled.Archive
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.notesai.Category import com.example.notesai.data.model.Note
import com.example.notesai.Note import com.example.notesai.data.model.Category
import com.example.notesai.presentation.components.EmptyState import com.example.notesai.presentation.components.EmptyState
import com.example.notesai.presentation.screens.archive.components.ArchiveNoteCard import com.example.notesai.presentation.screens.archive.components.ArchiveNoteCard

View File

@ -24,7 +24,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color 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.Note import com.example.notesai.data.model.Note
@Composable @Composable
fun ArchiveNoteCard( fun ArchiveNoteCard(

View File

@ -1,10 +1,7 @@
// File: presentation/screens/main/MainScreen.kt
package com.example.notesai.presentation.screens.main package com.example.notesai.presentation.screens.main
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.items import androidx.compose.foundation.lazy.staggeredgrid.items
@ -15,12 +12,12 @@ import androidx.compose.material.icons.filled.Search
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.notesai.Category import com.example.notesai.data.model.Category
import com.example.notesai.Note import com.example.notesai.data.model.Note
import com.example.notesai.presentation.components.EmptyState import com.example.notesai.presentation.components.EmptyState
import com.example.notesai.presentation.screens.main.components.CategoryCard import com.example.notesai.presentation.screens.main.components.CategoryCard
import com.example.notesai.presentation.screens.main.components.NoteCard
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun MainScreen( fun MainScreen(
categories: List<Category>, categories: List<Category>,
@ -30,7 +27,8 @@ fun MainScreen(
onCategoryClick: (Category) -> Unit, onCategoryClick: (Category) -> Unit,
onNoteClick: (Note) -> Unit, onNoteClick: (Note) -> Unit,
onPinToggle: (Note) -> Unit, onPinToggle: (Note) -> Unit,
onCategoryDelete: (Category) -> Unit onCategoryDelete: (Category) -> Unit,
onCategoryEdit: (Category, String, Long, Long) -> Unit // Parameter baru
) { ) {
Column(modifier = Modifier.fillMaxSize()) { Column(modifier = Modifier.fillMaxSize()) {
if (selectedCategory == null) { if (selectedCategory == null) {
@ -68,10 +66,15 @@ fun MainScreen(
items(filteredCategories) { category -> items(filteredCategories) { category ->
CategoryCard( CategoryCard(
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) },
onDelete = { onDelete = { onCategoryDelete(category) },
onCategoryDelete(category) onEdit = { name, gradientStart, gradientEnd ->
onCategoryEdit(category, name, gradientStart, gradientEnd)
} }
) )
} }
@ -108,16 +111,11 @@ fun MainScreen(
NoteCard( NoteCard(
note = note, note = note,
onClick = { onNoteClick(note) }, onClick = { onNoteClick(note) },
onPinClick = { onPinToggle(note) }, onPinClick = { onPinToggle(note) }
) )
} }
} }
} }
} }
} }
}
@Composable
fun NoteCard(note: Note, onClick: () -> Unit, onPinClick: () -> Unit) {
TODO("Not yet implemented")
} }

View File

@ -1,58 +1,44 @@
package com.example.notesai.presentation.screens.main.components package com.example.notesai.presentation.screens.main.components
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.filled.Folder import androidx.compose.material3.*
import androidx.compose.material3.AlertDialog import androidx.compose.runtime.*
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color 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.Category import com.example.notesai.data.model.Category
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun CategoryCard( fun CategoryCard(
category: Category, category: Category,
noteCount: Int, noteCount: Int,
onClick: () -> Unit, onClick: () -> Unit,
onDelete: () -> Unit = {} onDelete: () -> Unit = {},
onEdit: (String, Long, Long) -> Unit = { _, _, _ -> }
) { ) {
var showDeleteConfirm by remember { mutableStateOf(false) } var showDeleteConfirm by remember { mutableStateOf(false) }
var showEditDialog by remember { mutableStateOf(false) }
var showMenu by remember { mutableStateOf(false) }
// Delete confirmation dialog // Delete Confirmation Dialog
if (showDeleteConfirm) { if (showDeleteConfirm) {
AlertDialog( AlertDialog(
onDismissRequest = { showDeleteConfirm = false }, onDismissRequest = { showDeleteConfirm = false },
title = { Text("Hapus Kategori?", color = Color.White) }, title = { Text("Pindahkan ke Sampah?", color = Color.White) },
text = { text = {
Text("Kategori '${category.name}' dan semua catatan di dalamnya akan dihapus. Tindakan ini tidak dapat dibatalkan.", color = Color.White) Text(
"Kategori '${category.name}' dan semua catatan di dalamnya akan dipindahkan ke sampah.",
color = Color.White
)
}, },
confirmButton = { confirmButton = {
Button( Button(
@ -81,6 +67,18 @@ fun CategoryCard(
) )
} }
// Edit Dialog
if (showEditDialog) {
EditCategoryDialog(
category = category,
onDismiss = { showEditDialog = false },
onSave = { name, gradientStart, gradientEnd ->
onEdit(name, gradientStart, gradientEnd)
showEditDialog = false
}
)
}
Card( Card(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -124,22 +122,199 @@ fun CategoryCard(
) )
} }
// Delete button di top-right corner // Menu Button (Titik Tiga)
IconButton( Box(
onClick = { modifier = Modifier.align(Alignment.TopEnd)
showDeleteConfirm = true
},
modifier = Modifier
.align(Alignment.TopEnd)
.size(40.dp)
) { ) {
Icon( IconButton(
Icons.Default.Close, onClick = { showMenu = true }
contentDescription = "Hapus kategori", ) {
tint = Color.White.copy(0.7f), Icon(
modifier = Modifier.size(20.dp) Icons.Default.MoreVert,
) contentDescription = "Menu",
tint = Color.White.copy(0.9f)
)
}
DropdownMenu(
expanded = showMenu,
onDismissRequest = { showMenu = false },
modifier = Modifier.background(Color(0xFF1E293B))
) {
DropdownMenuItem(
text = {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
Icons.Default.Edit,
contentDescription = null,
tint = Color(0xFF6366F1),
modifier = Modifier.size(20.dp)
)
Text("Edit Kategori", color = Color.White)
}
},
onClick = {
showMenu = false
showEditDialog = true
}
)
DropdownMenuItem(
text = {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
Icons.Default.Delete,
contentDescription = null,
tint = Color(0xFFEF4444),
modifier = Modifier.size(20.dp)
)
Text("Pindah ke Sampah", color = Color.White)
}
},
onClick = {
showMenu = false
showDeleteConfirm = true
}
)
}
} }
} }
} }
}
@Composable
fun EditCategoryDialog(
category: Category,
onDismiss: () -> Unit,
onSave: (String, Long, Long) -> Unit
) {
val gradients = listOf(
Pair(0xFF6366F1L, 0xFFA855F7L),
Pair(0xFFEC4899L, 0xFFF59E0BL),
Pair(0xFF8B5CF6L, 0xFFEC4899L),
Pair(0xFF06B6D4L, 0xFF3B82F6L),
Pair(0xFF10B981L, 0xFF059669L),
Pair(0xFFF59E0BL, 0xFFEF4444L),
Pair(0xFF6366F1L, 0xFF8B5CF6L),
Pair(0xFFEF4444L, 0xFFDC2626L)
)
var name by remember { mutableStateOf(category.name) }
var selectedGradient by remember {
mutableStateOf(
gradients.indexOfFirst {
it.first == category.gradientStart && it.second == category.gradientEnd
}.takeIf { it >= 0 } ?: 0
)
}
AlertDialog(
onDismissRequest = onDismiss,
containerColor = Color(0xFF1E293B),
title = {
Text(
"Edit Kategori",
color = Color.White,
fontWeight = FontWeight.Bold
)
},
text = {
Column {
OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("Nama Kategori", color = Color(0xFF94A3B8)) },
modifier = Modifier.fillMaxWidth(),
colors = TextFieldDefaults.colors(
focusedTextColor = Color.White,
unfocusedTextColor = Color.White,
focusedContainerColor = Color(0xFF334155),
unfocusedContainerColor = Color(0xFF334155),
cursorColor = Color(0xFFA855F7),
focusedIndicatorColor = Color(0xFFA855F7),
unfocusedIndicatorColor = Color(0xFF64748B)
),
shape = RoundedCornerShape(12.dp)
)
Spacer(modifier = Modifier.height(20.dp))
Text(
"Pilih Gradient:",
style = MaterialTheme.typography.bodyMedium,
color = Color.White,
fontWeight = FontWeight.SemiBold
)
Spacer(modifier = Modifier.height(12.dp))
gradients.chunked(4).forEach { row ->
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
row.forEachIndexed { _, gradient ->
val globalIndex = gradients.indexOf(gradient)
Box(
modifier = Modifier
.weight(1f)
.aspectRatio(1f)
.clip(RoundedCornerShape(12.dp))
.background(
brush = Brush.linearGradient(
colors = listOf(
Color(gradient.first),
Color(gradient.second)
)
)
)
.clickable { selectedGradient = globalIndex },
contentAlignment = Alignment.Center
) {
if (selectedGradient == globalIndex) {
Icon(
Icons.Default.Check,
contentDescription = null,
tint = Color.White,
modifier = Modifier.size(24.dp)
)
}
}
}
}
Spacer(modifier = Modifier.height(8.dp))
}
}
},
confirmButton = {
Button(
onClick = {
if (name.isNotBlank()) {
val gradient = gradients[selectedGradient]
onSave(name, gradient.first, gradient.second)
}
},
enabled = name.isNotBlank(),
colors = ButtonDefaults.buttonColors(
containerColor = Color.Transparent
),
modifier = Modifier.background(
brush = Brush.linearGradient(
colors = listOf(Color(0xFF6366F1), Color(0xFFA855F7))
),
shape = RoundedCornerShape(8.dp)
)
) {
Text("Simpan", color = Color.White, fontWeight = FontWeight.Bold)
}
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text("Batal", color = Color(0xFF94A3B8))
}
}
)
} }

View File

@ -16,7 +16,6 @@ import androidx.compose.material.icons.filled.Star
import androidx.compose.material.icons.outlined.StarBorder import androidx.compose.material.icons.outlined.StarBorder
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Divider
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
@ -30,8 +29,7 @@ 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 androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.example.notesai.Note import com.example.notesai.data.model.Note
import com.example.notesai.util.Constants.AppColors.Divider
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
@ -112,7 +110,7 @@ fun NoteCard(
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
Divider( HorizontalDivider(
color = Color(0xFF334155), color = Color(0xFF334155),
thickness = 1.dp thickness = 1.dp
) )

View File

@ -39,8 +39,7 @@ 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 androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.example.notesai.Note import com.example.notesai.data.model.Note
import com.example.notesai.util.Constants.AppColors.Divider
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale

View File

@ -1,4 +1,4 @@
package com.example.notesai.presentation.screens.starred.components package com.example.notesai.presentation.screens.starred
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
@ -9,10 +9,10 @@ import androidx.compose.material.icons.filled.Star
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.notesai.Category
import com.example.notesai.Note
import com.example.notesai.presentation.components.EmptyState import com.example.notesai.presentation.components.EmptyState
import com.example.notesai.presentation.screens.starred.StarredNoteCard import com.example.notesai.presentation.screens.starred.components.StarredNoteCard
import com.example.notesai.data.model.Note
import com.example.notesai.data.model.Category
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable

View File

@ -1,4 +1,4 @@
package com.example.notesai.presentation.screens.starred package com.example.notesai.presentation.screens.starred.components
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -28,7 +28,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight 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.Note import com.example.notesai.data.model.Note
@Composable @Composable
fun StarredNoteCard( fun StarredNoteCard(

View File

@ -1,4 +1,4 @@
package com.example.notesai.presentation.screens.trash.components package com.example.notesai.presentation.screens.trash
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
@ -8,9 +8,10 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Delete
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.notesai.Category
import com.example.notesai.Note
import com.example.notesai.presentation.components.EmptyState import com.example.notesai.presentation.components.EmptyState
import com.example.notesai.presentation.screens.trash.components.TrashNoteCard
import com.example.notesai.data.model.Note
import com.example.notesai.data.model.Category
@Composable @Composable
fun TrashScreen( fun TrashScreen(

View File

@ -24,7 +24,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color 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.Note import com.example.notesai.data.model.Note
@Composable @Composable
fun TrashNoteCard( fun TrashNoteCard(

View File

@ -24,4 +24,8 @@ fun <T> List<T>.replaceWhere(predicate: (T) -> Boolean, transform: (T) -> T): Li
fun <T> List<T>.removeWhere(predicate: (T) -> Boolean): List<T> { fun <T> List<T>.removeWhere(predicate: (T) -> Boolean): List<T> {
return this.filter { !predicate(it) } return this.filter { !predicate(it) }
}
fun <T> List<T>.updateWhere(predicate: (T) -> Boolean, transform: (T) -> T): List<T> {
return this.map { if (predicate(it)) transform(it) else it }
} }