Menambahkan Dark/Light theme toggle
This commit is contained in:
parent
0876c82abc
commit
1b5e79166c
4
.idea/deploymentTargetSelector.xml
generated
4
.idea/deploymentTargetSelector.xml
generated
@ -4,10 +4,10 @@
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2025-12-13T07:41:36.634314200Z">
|
||||
<DropdownSelection timestamp="2025-12-18T02:27:11.898714800Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=RR8T103A6JZ" />
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Fazri Abdurrahman\.android\avd\Medium_Tablet.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
|
||||
@ -39,11 +39,13 @@ 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 com.example.notesai.util.AppColors
|
||||
|
||||
// File: MainActivity.kt (Bagian Theme Setup)
|
||||
// Ganti MaterialTheme di setContent dengan ini:
|
||||
|
||||
import com.example.notesai.util.Constants
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -52,34 +54,34 @@ class MainActivity : ComponentActivity() {
|
||||
MaterialTheme(
|
||||
colorScheme = darkColorScheme(
|
||||
// Primary colors
|
||||
primary = Constants.AppColors.Primary,
|
||||
primary = AppColors.Primary,
|
||||
onPrimary = Color.White,
|
||||
primaryContainer = Constants.AppColors.PrimaryContainer,
|
||||
primaryContainer = AppColors.PrimaryContainer,
|
||||
onPrimaryContainer = Color.White,
|
||||
|
||||
// Secondary colors
|
||||
secondary = Constants.AppColors.Secondary,
|
||||
secondary = AppColors.Secondary,
|
||||
onSecondary = Color.White,
|
||||
secondaryContainer = Constants.AppColors.SecondaryVariant,
|
||||
secondaryContainer = AppColors.SecondaryVariant,
|
||||
onSecondaryContainer = Color.White,
|
||||
|
||||
// Background colors
|
||||
background = Constants.AppColors.Background,
|
||||
onBackground = Constants.AppColors.OnBackground,
|
||||
background = AppColors.Background,
|
||||
onBackground = AppColors.OnBackground,
|
||||
|
||||
// Surface colors
|
||||
surface = Constants.AppColors.Surface,
|
||||
onSurface = Constants.AppColors.OnSurface,
|
||||
surfaceVariant = Constants.AppColors.SurfaceVariant,
|
||||
onSurfaceVariant = Constants.AppColors.OnSurfaceVariant,
|
||||
surface = AppColors.Surface,
|
||||
onSurface = AppColors.OnSurface,
|
||||
surfaceVariant = AppColors.SurfaceVariant,
|
||||
onSurfaceVariant = AppColors.OnSurfaceVariant,
|
||||
|
||||
// Error colors
|
||||
error = Constants.AppColors.Error,
|
||||
error = AppColors.Error,
|
||||
onError = Color.White,
|
||||
|
||||
// Other
|
||||
outline = Constants.AppColors.Border,
|
||||
outlineVariant = Constants.AppColors.Divider
|
||||
outline = AppColors.Border,
|
||||
outlineVariant = AppColors.Divider
|
||||
),
|
||||
typography = Typography(
|
||||
// Improve typography for better readability
|
||||
@ -131,6 +133,17 @@ fun NotesApp() {
|
||||
var showFullScreenNote by remember { mutableStateOf(false) }
|
||||
var fullScreenNote by remember { mutableStateOf<Note?>(null) }
|
||||
|
||||
// Theme state
|
||||
var isDarkTheme by remember { mutableStateOf(true) }
|
||||
|
||||
// Load theme preference - SET THEME HERE
|
||||
LaunchedEffect(Unit) {
|
||||
dataStoreManager.themeFlow.collect { theme ->
|
||||
isDarkTheme = theme == "dark"
|
||||
AppColors.setTheme(isDarkTheme) // SET GLOBAL THEME
|
||||
}
|
||||
}
|
||||
|
||||
// Load data dari DataStore
|
||||
LaunchedEffect(Unit) {
|
||||
try {
|
||||
@ -176,12 +189,10 @@ fun NotesApp() {
|
||||
}
|
||||
}
|
||||
|
||||
// Provide theme colors
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
Scaffold(
|
||||
// Di MainActivity.kt, ubah bagian topBar menjadi:
|
||||
|
||||
topBar = {
|
||||
// Hide TopBar untuk AI Helper screen dan FullScreen Note
|
||||
if (!showFullScreenNote && currentScreen != "ai") {
|
||||
ModernTopBar(
|
||||
title = when(currentScreen) {
|
||||
@ -210,12 +221,7 @@ fun NotesApp() {
|
||||
floatingActionButton = {
|
||||
AnimatedVisibility(
|
||||
visible = currentScreen == "main" && !showFullScreenNote,
|
||||
enter = scaleIn(
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioMediumBouncy,
|
||||
stiffness = Spring.StiffnessLow
|
||||
)
|
||||
) + fadeIn(),
|
||||
enter = scaleIn() + fadeIn(),
|
||||
exit = scaleOut() + fadeOut()
|
||||
) {
|
||||
FloatingActionButton(
|
||||
@ -227,19 +233,10 @@ fun NotesApp() {
|
||||
showCategoryDialog = true
|
||||
}
|
||||
},
|
||||
containerColor = Constants.AppColors.Primary,
|
||||
contentColor = Color.White,
|
||||
elevation = FloatingActionButtonDefaults.elevation(
|
||||
defaultElevation = 8.dp,
|
||||
pressedElevation = 12.dp
|
||||
),
|
||||
modifier = Modifier.size(64.dp)
|
||||
containerColor = AppColors.Primary,
|
||||
contentColor = Color.White
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Add,
|
||||
contentDescription = if (selectedCategory != null) "Tambah Catatan" else "Tambah Kategori",
|
||||
modifier = Modifier.size(28.dp)
|
||||
)
|
||||
Icon(Icons.Default.Add, contentDescription = "Add")
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -254,7 +251,8 @@ fun NotesApp() {
|
||||
onAIClick = { currentScreen = "ai" }
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
containerColor = AppColors.Background // SET BACKGROUND HERE
|
||||
) { padding ->
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
if (showFullScreenNote && fullScreenNote != null) {
|
||||
@ -486,19 +484,15 @@ fun NotesApp() {
|
||||
}
|
||||
}
|
||||
|
||||
// Drawer with Animation - DI LUAR SCAFFOLD agar di atas semua
|
||||
// Drawer with theme toggle
|
||||
AnimatedVisibility(
|
||||
visible = drawerState,
|
||||
enter = fadeIn() + slideInHorizontally(
|
||||
initialOffsetX = { -it }
|
||||
),
|
||||
exit = fadeOut() + slideOutHorizontally(
|
||||
targetOffsetX = { -it }
|
||||
),
|
||||
modifier = Modifier.zIndex(100f) // Z-index tinggi
|
||||
enter = fadeIn() + slideInHorizontally { -it },
|
||||
exit = fadeOut() + slideOutHorizontally { -it }
|
||||
) {
|
||||
DrawerMenu(
|
||||
currentScreen = currentScreen,
|
||||
isDarkTheme = isDarkTheme,
|
||||
onDismiss = { drawerState = false },
|
||||
onItemClick = { screen ->
|
||||
currentScreen = screen
|
||||
@ -506,9 +500,15 @@ fun NotesApp() {
|
||||
drawerState = false
|
||||
showSearch = false
|
||||
searchQuery = ""
|
||||
},
|
||||
onThemeToggle = {
|
||||
isDarkTheme = !isDarkTheme
|
||||
AppColors.setTheme(isDarkTheme) // UPDATE THEME
|
||||
scope.launch {
|
||||
dataStoreManager.saveTheme(if (isDarkTheme) "dark" else "light")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -50,7 +50,8 @@ class DataStoreManager(private val context: Context) {
|
||||
companion object {
|
||||
val CATEGORIES_KEY = stringPreferencesKey("categories")
|
||||
val NOTES_KEY = stringPreferencesKey("notes")
|
||||
val CHAT_HISTORY_KEY = stringPreferencesKey("chat_history") // NEW
|
||||
val CHAT_HISTORY_KEY = stringPreferencesKey("chat_history")
|
||||
val THEME_KEY = stringPreferencesKey("theme") // NEW: "dark" or "light"
|
||||
}
|
||||
|
||||
private val json = Json {
|
||||
@ -219,4 +220,28 @@ class DataStoreManager(private val context: Context) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
// NEW: Theme Preference Flow
|
||||
val themeFlow: Flow<String> = context.dataStore.data
|
||||
.catch { exception ->
|
||||
if (exception is IOException) {
|
||||
emit(emptyPreferences())
|
||||
} else {
|
||||
throw exception
|
||||
}
|
||||
}
|
||||
.map { preferences ->
|
||||
preferences[THEME_KEY] ?: "dark" // Default dark theme
|
||||
}
|
||||
|
||||
// NEW: Save Theme Preference
|
||||
suspend fun saveTheme(theme: String) {
|
||||
try {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[THEME_KEY] = theme
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,11 @@
|
||||
package com.example.notesai.data.model
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
//noinspection UnsafeOptInUsageError
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.util.UUID
|
||||
|
||||
@SuppressLint("UnsafeOptInUsageError")
|
||||
@Serializable
|
||||
data class Note(
|
||||
val id: String = UUID.randomUUID().toString(),
|
||||
|
||||
@ -26,6 +26,7 @@ import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.data.model.ChatHistory
|
||||
import com.example.notesai.data.model.Category
|
||||
import com.example.notesai.data.model.Note
|
||||
import com.example.notesai.util.AppColors
|
||||
import com.example.notesai.util.Constants
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
@ -56,7 +57,7 @@ fun ChatHistoryDrawer(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Constants.AppColors.Overlay)
|
||||
.background(AppColors.Overlay)
|
||||
.clickable(
|
||||
onClick = onDismiss,
|
||||
indication = null,
|
||||
@ -74,7 +75,7 @@ fun ChatHistoryDrawer(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
),
|
||||
color = Constants.AppColors.Surface,
|
||||
color = AppColors.Surface,
|
||||
shadowElevation = Constants.Elevation.ExtraLarge.dp
|
||||
) {
|
||||
Column(
|
||||
@ -87,7 +88,7 @@ fun ChatHistoryDrawer(
|
||||
.background(
|
||||
brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
Constants.AppColors.Primary.copy(alpha = 0.15f),
|
||||
AppColors.Primary.copy(alpha = 0.15f),
|
||||
Color.Transparent
|
||||
)
|
||||
)
|
||||
@ -103,7 +104,7 @@ fun ChatHistoryDrawer(
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
.background(
|
||||
color = Constants.AppColors.Primary.copy(alpha = 0.2f),
|
||||
color = AppColors.Primary.copy(alpha = 0.2f),
|
||||
shape = RoundedCornerShape(Constants.Radius.Medium.dp)
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
@ -111,7 +112,7 @@ fun ChatHistoryDrawer(
|
||||
Icon(
|
||||
Icons.Default.History,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
}
|
||||
@ -119,7 +120,7 @@ fun ChatHistoryDrawer(
|
||||
Text(
|
||||
"Riwayat Chat",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
@ -129,7 +130,7 @@ fun ChatHistoryDrawer(
|
||||
Text(
|
||||
"${chatHistories.size} percakapan tersimpan",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = Constants.AppColors.OnSurfaceVariant
|
||||
color = AppColors.OnSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -145,7 +146,7 @@ fun ChatHistoryDrawer(
|
||||
Text(
|
||||
"Filter Kategori",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = Constants.AppColors.OnSurfaceTertiary,
|
||||
color = AppColors.OnSurfaceTertiary,
|
||||
fontSize = 12.sp
|
||||
)
|
||||
|
||||
@ -156,7 +157,7 @@ fun ChatHistoryDrawer(
|
||||
onClick = { showCategoryDropdown = !showCategoryDropdown },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = Constants.AppColors.SurfaceVariant
|
||||
containerColor = AppColors.SurfaceVariant
|
||||
),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
) {
|
||||
@ -174,12 +175,12 @@ fun ChatHistoryDrawer(
|
||||
Icon(
|
||||
Icons.Default.Folder,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Text(
|
||||
selectedCategory?.name ?: "Semua Kategori",
|
||||
color = Constants.AppColors.OnSurface,
|
||||
color = AppColors.OnSurface,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 14.sp
|
||||
@ -188,7 +189,7 @@ fun ChatHistoryDrawer(
|
||||
Icon(
|
||||
Icons.Default.ArrowDropDown,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.OnSurfaceVariant
|
||||
tint = AppColors.OnSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -198,7 +199,7 @@ fun ChatHistoryDrawer(
|
||||
onDismissRequest = { showCategoryDropdown = false },
|
||||
modifier = Modifier
|
||||
.width(280.dp)
|
||||
.background(Constants.AppColors.SurfaceElevated)
|
||||
.background(AppColors.SurfaceElevated)
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
@ -209,12 +210,12 @@ fun ChatHistoryDrawer(
|
||||
Icon(
|
||||
Icons.Default.Folder,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.OnSurfaceVariant,
|
||||
tint = AppColors.OnSurfaceVariant,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Text(
|
||||
"Semua Kategori",
|
||||
color = Constants.AppColors.OnSurface
|
||||
color = AppColors.OnSurface
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -228,7 +229,7 @@ fun ChatHistoryDrawer(
|
||||
Icon(
|
||||
Icons.Default.Check,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
@ -236,7 +237,7 @@ fun ChatHistoryDrawer(
|
||||
)
|
||||
|
||||
if (categoriesWithNotes.isNotEmpty()) {
|
||||
HorizontalDivider(color = Constants.AppColors.Divider)
|
||||
HorizontalDivider(color = AppColors.Divider)
|
||||
}
|
||||
|
||||
categoriesWithNotes.forEach { category ->
|
||||
@ -263,12 +264,12 @@ fun ChatHistoryDrawer(
|
||||
)
|
||||
Text(
|
||||
category.name,
|
||||
color = Constants.AppColors.OnSurface
|
||||
color = AppColors.OnSurface
|
||||
)
|
||||
}
|
||||
|
||||
Surface(
|
||||
color = Constants.AppColors.Primary.copy(alpha = 0.15f),
|
||||
color = AppColors.Primary.copy(alpha = 0.15f),
|
||||
shape = RoundedCornerShape(Constants.Radius.Small.dp)
|
||||
) {
|
||||
Text(
|
||||
@ -277,7 +278,7 @@ fun ChatHistoryDrawer(
|
||||
horizontal = 8.dp,
|
||||
vertical = 2.dp
|
||||
),
|
||||
color = Constants.AppColors.Primary,
|
||||
color = AppColors.Primary,
|
||||
fontSize = 11.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
@ -294,7 +295,7 @@ fun ChatHistoryDrawer(
|
||||
Icon(
|
||||
Icons.Default.Check,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
@ -308,7 +309,7 @@ fun ChatHistoryDrawer(
|
||||
Spacer(modifier = Modifier.height(Constants.Spacing.Medium.dp))
|
||||
|
||||
HorizontalDivider(
|
||||
color = Constants.AppColors.Divider,
|
||||
color = AppColors.Divider,
|
||||
modifier = Modifier.padding(horizontal = Constants.Spacing.Large.dp)
|
||||
)
|
||||
|
||||
@ -335,18 +336,18 @@ fun ChatHistoryDrawer(
|
||||
Icons.Default.ChatBubbleOutline,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(48.dp),
|
||||
tint = Constants.AppColors.OnSurfaceVariant
|
||||
tint = AppColors.OnSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Belum ada riwayat chat",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Constants.AppColors.OnSurfaceVariant,
|
||||
color = AppColors.OnSurfaceVariant,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
Text(
|
||||
"Mulai chat dengan AI",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = Constants.AppColors.OnSurfaceTertiary
|
||||
color = AppColors.OnSurfaceTertiary
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -368,19 +369,19 @@ fun ChatHistoryDrawer(
|
||||
Icon(
|
||||
Icons.Default.Folder,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Text(
|
||||
categoryInfo.second,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = Constants.AppColors.OnSurfaceVariant,
|
||||
color = AppColors.OnSurfaceVariant,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 13.sp
|
||||
)
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.weight(1f),
|
||||
color = Constants.AppColors.Divider
|
||||
color = AppColors.Divider
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -413,7 +414,7 @@ private fun ChatHistoryItem(
|
||||
onClick = onClick,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = Constants.AppColors.SurfaceVariant
|
||||
containerColor = AppColors.SurfaceVariant
|
||||
),
|
||||
shape = RoundedCornerShape(Constants.Radius.Medium.dp)
|
||||
) {
|
||||
@ -429,7 +430,7 @@ private fun ChatHistoryItem(
|
||||
) {
|
||||
// Message Count
|
||||
Surface(
|
||||
color = Constants.AppColors.Primary.copy(alpha = 0.15f),
|
||||
color = AppColors.Primary.copy(alpha = 0.15f),
|
||||
shape = RoundedCornerShape(Constants.Radius.Small.dp)
|
||||
) {
|
||||
Row(
|
||||
@ -443,12 +444,12 @@ private fun ChatHistoryItem(
|
||||
Icon(
|
||||
Icons.Default.Chat,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(12.dp)
|
||||
)
|
||||
Text(
|
||||
"${history.messages.size}",
|
||||
color = Constants.AppColors.Primary,
|
||||
color = AppColors.Primary,
|
||||
fontSize = 11.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
@ -463,7 +464,7 @@ private fun ChatHistoryItem(
|
||||
Icon(
|
||||
Icons.Default.Delete,
|
||||
contentDescription = "Delete",
|
||||
tint = Constants.AppColors.Error,
|
||||
tint = AppColors.Error,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -475,7 +476,7 @@ private fun ChatHistoryItem(
|
||||
Text(
|
||||
history.lastMessagePreview,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Constants.AppColors.OnSurface,
|
||||
color = AppColors.OnSurface,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
fontSize = 14.sp
|
||||
@ -487,7 +488,7 @@ private fun ChatHistoryItem(
|
||||
Text(
|
||||
dateFormat.format(Date(history.timestamp)),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = Constants.AppColors.OnSurfaceTertiary,
|
||||
color = AppColors.OnSurfaceTertiary,
|
||||
fontSize = 12.sp
|
||||
)
|
||||
}
|
||||
@ -501,7 +502,7 @@ private fun ChatHistoryItem(
|
||||
Icon(
|
||||
Icons.Default.DeleteForever,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Error
|
||||
tint = AppColors.Error
|
||||
)
|
||||
},
|
||||
title = {
|
||||
@ -520,7 +521,7 @@ private fun ChatHistoryItem(
|
||||
showDeleteConfirm = false
|
||||
},
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Constants.AppColors.Error
|
||||
containerColor = AppColors.Error
|
||||
)
|
||||
) {
|
||||
Text("Hapus")
|
||||
@ -531,7 +532,7 @@ private fun ChatHistoryItem(
|
||||
Text("Batal")
|
||||
}
|
||||
},
|
||||
containerColor = Constants.AppColors.SurfaceElevated
|
||||
containerColor = AppColors.SurfaceElevated
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -24,18 +24,22 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.util.Constants
|
||||
import com.example.notesai.util.AppColors
|
||||
|
||||
|
||||
@Composable
|
||||
fun DrawerMenu(
|
||||
currentScreen: String,
|
||||
isDarkTheme: Boolean,
|
||||
onDismiss: () -> Unit,
|
||||
onItemClick: (String) -> Unit
|
||||
onItemClick: (String) -> Unit,
|
||||
onThemeToggle: () -> Unit
|
||||
) {
|
||||
// Backdrop with blur effect
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Constants.AppColors.Overlay)
|
||||
.background(AppColors.Overlay)
|
||||
.clickable(
|
||||
onClick = onDismiss,
|
||||
indication = null,
|
||||
@ -53,7 +57,7 @@ fun DrawerMenu(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
),
|
||||
color = Constants.AppColors.Surface,
|
||||
color = AppColors.Surface,
|
||||
shadowElevation = Constants.Elevation.ExtraLarge.dp
|
||||
) {
|
||||
Column(
|
||||
@ -66,7 +70,7 @@ fun DrawerMenu(
|
||||
.background(
|
||||
brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
Constants.AppColors.Primary.copy(alpha = 0.15f),
|
||||
AppColors.Primary.copy(alpha = 0.15f),
|
||||
Color.Transparent
|
||||
)
|
||||
)
|
||||
@ -79,7 +83,7 @@ fun DrawerMenu(
|
||||
modifier = Modifier
|
||||
.size(56.dp)
|
||||
.background(
|
||||
color = Constants.AppColors.Primary.copy(alpha = 0.2f),
|
||||
color = AppColors.Primary.copy(alpha = 0.2f),
|
||||
shape = RoundedCornerShape(Constants.Radius.Medium.dp)
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
@ -87,7 +91,7 @@ fun DrawerMenu(
|
||||
Icon(
|
||||
Icons.Default.Create,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(32.dp)
|
||||
)
|
||||
}
|
||||
@ -97,7 +101,7 @@ fun DrawerMenu(
|
||||
Text(
|
||||
Constants.APP_NAME,
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 24.sp
|
||||
)
|
||||
@ -107,7 +111,7 @@ fun DrawerMenu(
|
||||
Text(
|
||||
"Smart Note Taking",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Constants.AppColors.OnSurfaceVariant,
|
||||
color = AppColors.OnSurfaceVariant,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
}
|
||||
@ -144,11 +148,26 @@ fun DrawerMenu(
|
||||
onClick = { onItemClick("trash") }
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(Constants.Spacing.Medium.dp))
|
||||
|
||||
HorizontalDivider(
|
||||
color = AppColors.Divider,
|
||||
modifier = Modifier.padding(horizontal = Constants.Spacing.Medium.dp)
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(Constants.Spacing.Medium.dp))
|
||||
|
||||
// Theme Toggle
|
||||
ThemeToggleItem(
|
||||
isDarkTheme = isDarkTheme,
|
||||
onToggle = onThemeToggle
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
// Footer - Version info
|
||||
HorizontalDivider(
|
||||
color = Constants.AppColors.Divider,
|
||||
color = AppColors.Divider,
|
||||
modifier = Modifier.padding(horizontal = Constants.Spacing.Medium.dp)
|
||||
)
|
||||
|
||||
@ -162,13 +181,13 @@ fun DrawerMenu(
|
||||
Text(
|
||||
"Version ${Constants.APP_VERSION}",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = Constants.AppColors.OnSurfaceTertiary,
|
||||
color = AppColors.OnSurfaceTertiary,
|
||||
fontSize = 12.sp
|
||||
)
|
||||
|
||||
// Powered by badge
|
||||
Surface(
|
||||
color = Constants.AppColors.Primary.copy(alpha = 0.1f),
|
||||
color = AppColors.Primary.copy(alpha = 0.1f),
|
||||
shape = RoundedCornerShape(Constants.Radius.Small.dp)
|
||||
) {
|
||||
Row(
|
||||
@ -179,12 +198,12 @@ fun DrawerMenu(
|
||||
Icon(
|
||||
Icons.Default.AutoAwesome,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(12.dp)
|
||||
)
|
||||
Text(
|
||||
"AI",
|
||||
color = Constants.AppColors.Primary,
|
||||
color = AppColors.Primary,
|
||||
fontSize = 11.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
@ -196,6 +215,76 @@ fun DrawerMenu(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ThemeToggleItem(
|
||||
isDarkTheme: Boolean,
|
||||
onToggle: () -> Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = Constants.Spacing.Medium.dp)
|
||||
.clip(RoundedCornerShape(Constants.Radius.Medium.dp))
|
||||
.clickable(onClick = onToggle)
|
||||
.background(AppColors.SurfaceVariant)
|
||||
.padding(horizontal = Constants.Spacing.Medium.dp, vertical = Constants.Spacing.Medium.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(Constants.Spacing.Medium.dp)
|
||||
) {
|
||||
// Icon with background
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.background(
|
||||
color = AppColors.Primary.copy(alpha = 0.2f),
|
||||
shape = CircleShape
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
if (isDarkTheme) Icons.Default.DarkMode else Icons.Default.LightMode,
|
||||
contentDescription = null,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
|
||||
// Text
|
||||
Column {
|
||||
Text(
|
||||
"Tema Aplikasi",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = AppColors.OnSurface,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 15.sp
|
||||
)
|
||||
Text(
|
||||
if (isDarkTheme) "Mode Gelap" else "Mode Terang",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = AppColors.OnSurfaceTertiary,
|
||||
fontSize = 12.sp
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle Switch
|
||||
Switch(
|
||||
checked = isDarkTheme,
|
||||
onCheckedChange = { onToggle() },
|
||||
colors = SwitchDefaults.colors(
|
||||
checkedThumbColor = Color.White,
|
||||
checkedTrackColor = AppColors.Primary,
|
||||
uncheckedThumbColor = Color.White,
|
||||
uncheckedTrackColor = AppColors.Border
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DrawerMenuItem(
|
||||
icon: ImageVector,
|
||||
@ -221,7 +310,7 @@ private fun DrawerMenuItem(
|
||||
.clickable(onClick = onClick)
|
||||
.background(
|
||||
color = if (isSelected)
|
||||
Constants.AppColors.Primary.copy(alpha = 0.1f)
|
||||
AppColors.Primary.copy(alpha = 0.1f)
|
||||
else
|
||||
Color.Transparent
|
||||
)
|
||||
@ -234,9 +323,9 @@ private fun DrawerMenuItem(
|
||||
.size(40.dp)
|
||||
.background(
|
||||
color = if (isSelected)
|
||||
Constants.AppColors.Primary.copy(alpha = 0.2f)
|
||||
AppColors.Primary.copy(alpha = 0.2f)
|
||||
else
|
||||
Constants.AppColors.SurfaceVariant,
|
||||
AppColors.SurfaceVariant,
|
||||
shape = CircleShape
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
@ -244,7 +333,7 @@ private fun DrawerMenuItem(
|
||||
Icon(
|
||||
icon,
|
||||
contentDescription = null,
|
||||
tint = if (isSelected) Constants.AppColors.Primary else Constants.AppColors.OnSurfaceVariant,
|
||||
tint = if (isSelected) AppColors.Primary else AppColors.OnSurfaceVariant,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
@ -255,7 +344,7 @@ private fun DrawerMenuItem(
|
||||
Text(
|
||||
text,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = if (isSelected) Constants.AppColors.Primary else Constants.AppColors.OnSurface,
|
||||
color = if (isSelected) AppColors.Primary else AppColors.OnSurface,
|
||||
fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal,
|
||||
fontSize = 15.sp
|
||||
)
|
||||
|
||||
@ -26,6 +26,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.util.AppColors
|
||||
import com.example.notesai.util.Constants
|
||||
|
||||
@Composable
|
||||
@ -47,7 +48,7 @@ fun ModernBottomBar(
|
||||
elevation = Constants.Elevation.Large.dp,
|
||||
shape = RoundedCornerShape(Constants.Radius.ExtraLarge.dp)
|
||||
),
|
||||
color = Constants.AppColors.SurfaceElevated,
|
||||
color = AppColors.SurfaceElevated,
|
||||
shape = RoundedCornerShape(Constants.Radius.ExtraLarge.dp)
|
||||
) {
|
||||
Row(
|
||||
@ -96,7 +97,7 @@ private fun BottomBarItem(
|
||||
|
||||
// Color animation
|
||||
val iconColor by animateColorAsState(
|
||||
targetValue = if (selected) Constants.AppColors.Primary else Constants.AppColors.OnSurfaceVariant,
|
||||
targetValue = if (selected) AppColors.Primary else AppColors.OnSurfaceVariant,
|
||||
animationSpec = tween(Constants.ANIMATION_DURATION_MEDIUM),
|
||||
label = "color"
|
||||
)
|
||||
@ -125,7 +126,7 @@ private fun BottomBarItem(
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.background(
|
||||
color = Constants.AppColors.Primary.copy(alpha = 0.15f),
|
||||
color = AppColors.Primary.copy(alpha = 0.15f),
|
||||
shape = CircleShape
|
||||
)
|
||||
)
|
||||
@ -148,7 +149,7 @@ private fun BottomBarItem(
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
label,
|
||||
color = Constants.AppColors.Primary,
|
||||
color = AppColors.Primary,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 12.sp
|
||||
|
||||
@ -19,6 +19,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.util.AppColors
|
||||
import com.example.notesai.util.Constants
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@ -48,7 +49,7 @@ fun ModernTopBar(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.shadow(Constants.Elevation.Small.dp),
|
||||
color = Constants.AppColors.Surface
|
||||
color = AppColors.Surface
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@ -63,16 +64,16 @@ fun ModernTopBar(
|
||||
placeholder = {
|
||||
Text(
|
||||
"Cari catatan atau kategori...",
|
||||
color = Constants.AppColors.OnSurfaceVariant,
|
||||
color = AppColors.OnSurfaceVariant,
|
||||
fontSize = 15.sp
|
||||
)
|
||||
},
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
focusedTextColor = Constants.AppColors.OnBackground,
|
||||
unfocusedTextColor = Constants.AppColors.OnSurface,
|
||||
cursorColor = Constants.AppColors.Primary,
|
||||
focusedContainerColor = AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = AppColors.SurfaceVariant,
|
||||
focusedTextColor = AppColors.OnBackground,
|
||||
unfocusedTextColor = AppColors.OnSurface,
|
||||
cursorColor = AppColors.Primary,
|
||||
focusedIndicatorColor = Color.Transparent,
|
||||
unfocusedIndicatorColor = Color.Transparent
|
||||
),
|
||||
@ -96,7 +97,7 @@ fun ModernTopBar(
|
||||
Icon(
|
||||
Icons.Default.Close,
|
||||
contentDescription = "Close Search",
|
||||
tint = Constants.AppColors.OnSurfaceVariant
|
||||
tint = AppColors.OnSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -107,7 +108,7 @@ fun ModernTopBar(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.shadow(Constants.Elevation.Small.dp),
|
||||
color = Constants.AppColors.Surface
|
||||
color = AppColors.Surface
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@ -120,7 +121,7 @@ fun ModernTopBar(
|
||||
Icon(
|
||||
if (showBackButton) Icons.AutoMirrored.Filled.ArrowBack else Icons.Default.Menu,
|
||||
contentDescription = if (showBackButton) "Back" else "Menu",
|
||||
tint = Constants.AppColors.OnSurface
|
||||
tint = AppColors.OnSurface
|
||||
)
|
||||
}
|
||||
|
||||
@ -129,7 +130,7 @@ fun ModernTopBar(
|
||||
title,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 20.sp,
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
|
||||
@ -138,7 +139,7 @@ fun ModernTopBar(
|
||||
Icon(
|
||||
Icons.Default.Search,
|
||||
contentDescription = "Search",
|
||||
tint = Constants.AppColors.OnSurfaceVariant
|
||||
tint = AppColors.OnSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.util.AppColors
|
||||
import com.example.notesai.util.Constants
|
||||
|
||||
@Composable
|
||||
@ -31,12 +32,12 @@ fun CategoryDialog(
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
containerColor = Constants.AppColors.Surface,
|
||||
containerColor = AppColors.Surface,
|
||||
shape = RoundedCornerShape(20.dp),
|
||||
title = {
|
||||
Text(
|
||||
"Buat Kategori Baru",
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 20.sp
|
||||
)
|
||||
@ -52,24 +53,24 @@ fun CategoryDialog(
|
||||
label = {
|
||||
Text(
|
||||
"Nama Kategori",
|
||||
color = Constants.AppColors.OnSurfaceVariant
|
||||
color = AppColors.OnSurfaceVariant
|
||||
)
|
||||
},
|
||||
placeholder = {
|
||||
Text(
|
||||
"Contoh: Pekerjaan, Personal",
|
||||
color = Constants.AppColors.OnSurfaceTertiary,
|
||||
color = AppColors.OnSurfaceTertiary,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = OutlinedTextFieldDefaults.colors(
|
||||
focusedTextColor = Constants.AppColors.OnBackground,
|
||||
unfocusedTextColor = Constants.AppColors.OnSurface,
|
||||
focusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
cursorColor = Constants.AppColors.Primary,
|
||||
focusedBorderColor = Constants.AppColors.Primary,
|
||||
focusedTextColor = AppColors.OnBackground,
|
||||
unfocusedTextColor = AppColors.OnSurface,
|
||||
focusedContainerColor = AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = AppColors.SurfaceVariant,
|
||||
cursorColor = AppColors.Primary,
|
||||
focusedBorderColor = AppColors.Primary,
|
||||
unfocusedBorderColor = Color.Transparent
|
||||
),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
@ -83,18 +84,18 @@ fun CategoryDialog(
|
||||
Text(
|
||||
"Pilih Warna:",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Constants.AppColors.OnSurface,
|
||||
color = AppColors.OnSurface,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
|
||||
Constants.AppColors.CategoryColors.chunked(4).forEach { row ->
|
||||
Constants.CategoryColors.chunked(4).forEach { row ->
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
row.forEach { gradient ->
|
||||
val globalIndex = Constants.AppColors.CategoryColors.indexOf(gradient)
|
||||
val globalIndex = Constants.CategoryColors.indexOf(gradient)
|
||||
val isSelected = selectedGradient == globalIndex
|
||||
|
||||
// Scale animation
|
||||
@ -120,11 +121,7 @@ fun CategoryDialog(
|
||||
)
|
||||
)
|
||||
)
|
||||
.clickable { selectedGradient = globalIndex }
|
||||
.then(
|
||||
if (isSelected) Modifier
|
||||
else Modifier
|
||||
),
|
||||
.clickable { selectedGradient = globalIndex },
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
// Check icon dengan animation
|
||||
@ -158,14 +155,14 @@ fun CategoryDialog(
|
||||
Button(
|
||||
onClick = {
|
||||
if (name.isNotBlank()) {
|
||||
val gradient = Constants.AppColors.CategoryColors[selectedGradient]
|
||||
val gradient = Constants.CategoryColors[selectedGradient]
|
||||
onSave(name, gradient.first, gradient.second)
|
||||
}
|
||||
},
|
||||
enabled = name.isNotBlank(),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Constants.AppColors.Primary,
|
||||
disabledContainerColor = Constants.AppColors.Primary.copy(alpha = 0.5f)
|
||||
containerColor = AppColors.Primary,
|
||||
disabledContainerColor = AppColors.Primary.copy(alpha = 0.5f)
|
||||
),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
modifier = Modifier.height(48.dp)
|
||||
@ -186,7 +183,7 @@ fun CategoryDialog(
|
||||
) {
|
||||
Text(
|
||||
"Batal",
|
||||
color = Constants.AppColors.OnSurfaceVariant,
|
||||
color = AppColors.OnSurfaceVariant,
|
||||
fontSize = 15.sp
|
||||
)
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.data.model.Note
|
||||
import com.example.notesai.util.AppColors
|
||||
import com.example.notesai.util.Constants
|
||||
|
||||
@Composable
|
||||
@ -29,19 +30,19 @@ fun NoteDialog(
|
||||
if (showDeleteConfirm) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showDeleteConfirm = false },
|
||||
containerColor = Constants.AppColors.Surface,
|
||||
containerColor = AppColors.Surface,
|
||||
shape = RoundedCornerShape(20.dp),
|
||||
title = {
|
||||
Text(
|
||||
"Hapus Catatan?",
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
"Catatan ini akan dipindahkan ke sampah.",
|
||||
color = Constants.AppColors.OnSurfaceVariant
|
||||
color = AppColors.OnSurfaceVariant
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
@ -51,7 +52,7 @@ fun NoteDialog(
|
||||
showDeleteConfirm = false
|
||||
},
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Constants.AppColors.Error
|
||||
containerColor = AppColors.Error
|
||||
),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
) {
|
||||
@ -63,7 +64,7 @@ fun NoteDialog(
|
||||
onClick = { showDeleteConfirm = false },
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
) {
|
||||
Text("Batal", color = Constants.AppColors.OnSurfaceVariant)
|
||||
Text("Batal", color = AppColors.OnSurfaceVariant)
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -71,12 +72,12 @@ fun NoteDialog(
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
containerColor = Constants.AppColors.Surface,
|
||||
containerColor = AppColors.Surface,
|
||||
shape = RoundedCornerShape(20.dp),
|
||||
title = {
|
||||
Text(
|
||||
if (note == null) "Catatan Baru" else "Edit Catatan",
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 20.sp
|
||||
)
|
||||
@ -92,24 +93,24 @@ fun NoteDialog(
|
||||
label = {
|
||||
Text(
|
||||
"Judul",
|
||||
color = Constants.AppColors.OnSurfaceVariant
|
||||
color = AppColors.OnSurfaceVariant
|
||||
)
|
||||
},
|
||||
placeholder = {
|
||||
Text(
|
||||
"Masukkan judul catatan",
|
||||
color = Constants.AppColors.OnSurfaceTertiary,
|
||||
color = AppColors.OnSurfaceTertiary,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = OutlinedTextFieldDefaults.colors(
|
||||
focusedTextColor = Constants.AppColors.OnBackground,
|
||||
unfocusedTextColor = Constants.AppColors.OnSurface,
|
||||
focusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
cursorColor = Constants.AppColors.Primary,
|
||||
focusedBorderColor = Constants.AppColors.Primary,
|
||||
focusedTextColor = AppColors.OnBackground,
|
||||
unfocusedTextColor = AppColors.OnSurface,
|
||||
focusedContainerColor = AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = AppColors.SurfaceVariant,
|
||||
cursorColor = AppColors.Primary,
|
||||
focusedBorderColor = AppColors.Primary,
|
||||
unfocusedBorderColor = Color.Transparent
|
||||
),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
@ -123,13 +124,13 @@ fun NoteDialog(
|
||||
label = {
|
||||
Text(
|
||||
"Deskripsi",
|
||||
color = Constants.AppColors.OnSurfaceVariant
|
||||
color = AppColors.OnSurfaceVariant
|
||||
)
|
||||
},
|
||||
placeholder = {
|
||||
Text(
|
||||
"Tambahkan deskripsi singkat...",
|
||||
color = Constants.AppColors.OnSurfaceTertiary,
|
||||
color = AppColors.OnSurfaceTertiary,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
},
|
||||
@ -137,12 +138,12 @@ fun NoteDialog(
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 120.dp, max = 200.dp),
|
||||
colors = OutlinedTextFieldDefaults.colors(
|
||||
focusedTextColor = Constants.AppColors.OnBackground,
|
||||
unfocusedTextColor = Constants.AppColors.OnSurface,
|
||||
focusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
cursorColor = Constants.AppColors.Primary,
|
||||
focusedBorderColor = Constants.AppColors.Primary,
|
||||
focusedTextColor = AppColors.OnBackground,
|
||||
unfocusedTextColor = AppColors.OnSurface,
|
||||
focusedContainerColor = AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = AppColors.SurfaceVariant,
|
||||
cursorColor = AppColors.Primary,
|
||||
focusedBorderColor = AppColors.Primary,
|
||||
unfocusedBorderColor = Color.Transparent
|
||||
),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
@ -163,7 +164,7 @@ fun NoteDialog(
|
||||
Icon(
|
||||
Icons.Default.Delete,
|
||||
contentDescription = "Hapus",
|
||||
tint = Constants.AppColors.Error
|
||||
tint = AppColors.Error
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -178,7 +179,7 @@ fun NoteDialog(
|
||||
) {
|
||||
Text(
|
||||
"Batal",
|
||||
color = Constants.AppColors.OnSurfaceVariant,
|
||||
color = AppColors.OnSurfaceVariant,
|
||||
fontSize = 15.sp
|
||||
)
|
||||
}
|
||||
@ -192,8 +193,8 @@ fun NoteDialog(
|
||||
},
|
||||
enabled = title.isNotBlank(),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Constants.AppColors.Primary,
|
||||
disabledContainerColor = Constants.AppColors.Primary.copy(alpha = 0.5f)
|
||||
containerColor = AppColors.Primary,
|
||||
disabledContainerColor = AppColors.Primary.copy(alpha = 0.5f)
|
||||
),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
modifier = Modifier.height(48.dp)
|
||||
@ -208,4 +209,4 @@ fun NoteDialog(
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -34,6 +34,7 @@ import com.example.notesai.presentation.screens.ai.components.ChatBubble
|
||||
import com.example.notesai.presentation.screens.ai.components.ChatHistoryDrawer
|
||||
import com.example.notesai.presentation.screens.ai.components.CompactStatItem
|
||||
import com.example.notesai.presentation.screens.ai.components.SuggestionChip
|
||||
import com.example.notesai.util.AppColors
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@ -128,11 +129,11 @@ fun AIHelperScreen(
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Constants.AppColors.Background)
|
||||
.background(AppColors.Background)
|
||||
) {
|
||||
// Top Bar with History Button & Stats
|
||||
Surface(
|
||||
color = Constants.AppColors.Surface,
|
||||
color = AppColors.Surface,
|
||||
shadowElevation = 2.dp
|
||||
) {
|
||||
Column(
|
||||
@ -152,21 +153,21 @@ fun AIHelperScreen(
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.background(
|
||||
Constants.AppColors.Primary.copy(alpha = 0.1f),
|
||||
AppColors.Primary.copy(alpha = 0.1f),
|
||||
CircleShape
|
||||
)
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Menu,
|
||||
contentDescription = "Menu",
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
|
||||
// Category Badge
|
||||
Surface(
|
||||
color = Constants.AppColors.Primary.copy(alpha = 0.1f),
|
||||
color = AppColors.Primary.copy(alpha = 0.1f),
|
||||
shape = RoundedCornerShape(Constants.Radius.Medium.dp)
|
||||
) {
|
||||
Row(
|
||||
@ -180,12 +181,12 @@ fun AIHelperScreen(
|
||||
Icon(
|
||||
Icons.Default.Folder,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Text(
|
||||
selectedCategory?.name ?: "Semua Kategori",
|
||||
color = Constants.AppColors.Primary,
|
||||
color = AppColors.Primary,
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
)
|
||||
@ -197,7 +198,7 @@ fun AIHelperScreen(
|
||||
Button(
|
||||
onClick = { startNewChat() },
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Constants.AppColors.Primary
|
||||
containerColor = AppColors.Primary
|
||||
),
|
||||
shape = RoundedCornerShape(Constants.Radius.Medium.dp),
|
||||
contentPadding = PaddingValues(
|
||||
@ -252,7 +253,7 @@ fun AIHelperScreen(
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalDivider(color = Constants.AppColors.Divider)
|
||||
HorizontalDivider(color = AppColors.Divider)
|
||||
|
||||
// Chat Area
|
||||
Box(
|
||||
@ -273,7 +274,7 @@ fun AIHelperScreen(
|
||||
modifier = Modifier
|
||||
.size(80.dp)
|
||||
.background(
|
||||
color = Constants.AppColors.Primary.copy(alpha = 0.1f),
|
||||
color = AppColors.Primary.copy(alpha = 0.1f),
|
||||
shape = CircleShape
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
@ -282,7 +283,7 @@ fun AIHelperScreen(
|
||||
Icons.Default.AutoAwesome,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(40.dp),
|
||||
tint = Constants.AppColors.Primary
|
||||
tint = AppColors.Primary
|
||||
)
|
||||
}
|
||||
|
||||
@ -291,7 +292,7 @@ fun AIHelperScreen(
|
||||
Text(
|
||||
"AI Assistant",
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
|
||||
@ -300,7 +301,7 @@ fun AIHelperScreen(
|
||||
Text(
|
||||
"Tanyakan apa saja tentang catatan Anda",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = Constants.AppColors.OnSurfaceVariant,
|
||||
color = AppColors.OnSurfaceVariant,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
@ -315,7 +316,7 @@ fun AIHelperScreen(
|
||||
Text(
|
||||
"Contoh pertanyaan:",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = Constants.AppColors.OnSurfaceTertiary
|
||||
color = AppColors.OnSurfaceTertiary
|
||||
)
|
||||
SuggestionChip("Analisis catatan saya") { prompt = it }
|
||||
SuggestionChip("Buat ringkasan") { prompt = it }
|
||||
@ -356,7 +357,7 @@ fun AIHelperScreen(
|
||||
horizontalArrangement = Arrangement.Start
|
||||
) {
|
||||
Surface(
|
||||
color = Constants.AppColors.SurfaceVariant,
|
||||
color = AppColors.SurfaceVariant,
|
||||
shape = RoundedCornerShape(16.dp)
|
||||
) {
|
||||
Row(
|
||||
@ -366,12 +367,12 @@ fun AIHelperScreen(
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
color = Constants.AppColors.Primary,
|
||||
color = AppColors.Primary,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
Text(
|
||||
"AI sedang berpikir...",
|
||||
color = Constants.AppColors.OnSurfaceVariant,
|
||||
color = AppColors.OnSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
@ -383,7 +384,7 @@ fun AIHelperScreen(
|
||||
if (errorMessage.isNotEmpty()) {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
color = Constants.AppColors.Error.copy(alpha = 0.1f),
|
||||
color = AppColors.Error.copy(alpha = 0.1f),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
) {
|
||||
Row(
|
||||
@ -394,12 +395,12 @@ fun AIHelperScreen(
|
||||
Icon(
|
||||
Icons.Default.Warning,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Error,
|
||||
tint = AppColors.Error,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Text(
|
||||
errorMessage,
|
||||
color = Constants.AppColors.Error,
|
||||
color = AppColors.Error,
|
||||
style = MaterialTheme.typography.bodySmall
|
||||
)
|
||||
}
|
||||
@ -411,7 +412,7 @@ fun AIHelperScreen(
|
||||
|
||||
// Input Area - Minimalist
|
||||
Surface(
|
||||
color = Constants.AppColors.Surface,
|
||||
color = AppColors.Surface,
|
||||
shadowElevation = 8.dp,
|
||||
shape = RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp)
|
||||
) {
|
||||
@ -428,19 +429,19 @@ fun AIHelperScreen(
|
||||
placeholder = {
|
||||
Text(
|
||||
"Ketik pesan...",
|
||||
color = Constants.AppColors.OnSurfaceTertiary
|
||||
color = AppColors.OnSurfaceTertiary
|
||||
)
|
||||
},
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.heightIn(min = 48.dp, max = 120.dp),
|
||||
colors = OutlinedTextFieldDefaults.colors(
|
||||
focusedTextColor = Constants.AppColors.OnBackground,
|
||||
unfocusedTextColor = Constants.AppColors.OnSurface,
|
||||
focusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
cursorColor = Constants.AppColors.Primary,
|
||||
focusedBorderColor = Constants.AppColors.Primary,
|
||||
focusedTextColor = AppColors.OnBackground,
|
||||
unfocusedTextColor = AppColors.OnSurface,
|
||||
focusedContainerColor = AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = AppColors.SurfaceVariant,
|
||||
cursorColor = AppColors.Primary,
|
||||
focusedBorderColor = AppColors.Primary,
|
||||
unfocusedBorderColor = Color.Transparent
|
||||
),
|
||||
shape = RoundedCornerShape(24.dp),
|
||||
@ -501,7 +502,7 @@ fun AIHelperScreen(
|
||||
}
|
||||
}
|
||||
},
|
||||
containerColor = Constants.AppColors.Primary,
|
||||
containerColor = AppColors.Primary,
|
||||
modifier = Modifier.size(48.dp)
|
||||
) {
|
||||
Icon(
|
||||
|
||||
@ -30,6 +30,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.data.model.ChatMessage
|
||||
import com.example.notesai.util.AppColors
|
||||
import com.example.notesai.util.Constants
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
@ -52,7 +53,7 @@ fun ChatBubble(
|
||||
modifier = Modifier
|
||||
.size(32.dp)
|
||||
.background(
|
||||
color = Constants.AppColors.Primary.copy(alpha = 0.1f),
|
||||
color = AppColors.Primary.copy(alpha = 0.1f),
|
||||
shape = CircleShape
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
@ -60,7 +61,7 @@ fun ChatBubble(
|
||||
Icon(
|
||||
Icons.Default.AutoAwesome,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
}
|
||||
@ -73,9 +74,9 @@ fun ChatBubble(
|
||||
) {
|
||||
Surface(
|
||||
color = if (message.isUser)
|
||||
Constants.AppColors.Primary
|
||||
AppColors.Primary
|
||||
else
|
||||
Constants.AppColors.SurfaceVariant,
|
||||
AppColors.SurfaceVariant,
|
||||
shape = RoundedCornerShape(
|
||||
topStart = 16.dp,
|
||||
topEnd = 16.dp,
|
||||
@ -86,7 +87,7 @@ fun ChatBubble(
|
||||
Column(modifier = Modifier.padding(12.dp)) {
|
||||
Text(
|
||||
message.message,
|
||||
color = if (message.isUser) Color.White else Constants.AppColors.OnSurface,
|
||||
color = if (message.isUser) Color.White else AppColors.OnSurface,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
lineHeight = 20.sp
|
||||
)
|
||||
@ -101,7 +102,7 @@ fun ChatBubble(
|
||||
color = if (message.isUser)
|
||||
Color.White.copy(0.7f)
|
||||
else
|
||||
Constants.AppColors.OnSurfaceTertiary,
|
||||
AppColors.OnSurfaceTertiary,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
fontSize = 11.sp,
|
||||
modifier = Modifier.padding(top = 4.dp)
|
||||
@ -115,7 +116,7 @@ fun ChatBubble(
|
||||
Icon(
|
||||
Icons.Default.ContentCopy,
|
||||
contentDescription = "Copy",
|
||||
tint = Constants.AppColors.OnSurfaceVariant,
|
||||
tint = AppColors.OnSurfaceVariant,
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
@ -127,7 +128,7 @@ fun ChatBubble(
|
||||
if (showCopied && !message.isUser) {
|
||||
Text(
|
||||
"✓ Disalin",
|
||||
color = Constants.AppColors.Success,
|
||||
color = AppColors.Success,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
fontSize = 11.sp,
|
||||
modifier = Modifier.padding(top = 4.dp, start = 8.dp)
|
||||
|
||||
@ -19,6 +19,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.util.AppColors
|
||||
import com.example.notesai.util.Constants
|
||||
|
||||
@Composable
|
||||
@ -32,7 +33,7 @@ fun CompactStatItem(
|
||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||
modifier = Modifier
|
||||
.background(
|
||||
color = Constants.AppColors.SurfaceVariant,
|
||||
color = AppColors.SurfaceVariant,
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
)
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
@ -40,21 +41,21 @@ fun CompactStatItem(
|
||||
Icon(
|
||||
icon,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
value,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 16.sp
|
||||
)
|
||||
Text(
|
||||
label,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = Constants.AppColors.OnSurfaceTertiary,
|
||||
color = AppColors.OnSurfaceTertiary,
|
||||
fontSize = 11.sp
|
||||
)
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.util.AppColors
|
||||
import com.example.notesai.util.Constants
|
||||
|
||||
@Composable
|
||||
@ -32,7 +33,7 @@ fun SuggestionChip(
|
||||
) {
|
||||
Surface(
|
||||
onClick = { onSelect(text) },
|
||||
color = Constants.AppColors.SurfaceVariant,
|
||||
color = AppColors.SurfaceVariant,
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
) {
|
||||
Row(
|
||||
@ -43,12 +44,12 @@ fun SuggestionChip(
|
||||
Icon(
|
||||
Icons.Default.Lightbulb,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Text(
|
||||
text,
|
||||
color = Constants.AppColors.OnSurface,
|
||||
color = AppColors.OnSurface,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
|
||||
@ -22,6 +22,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.data.model.Category
|
||||
import com.example.notesai.util.AppColors
|
||||
import com.example.notesai.util.Constants
|
||||
|
||||
@Composable
|
||||
@ -54,14 +55,14 @@ fun CategoryCard(
|
||||
title = {
|
||||
Text(
|
||||
"Pindahkan ke Sampah?",
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
"Kategori '${category.name}' dan $noteCount catatan di dalamnya akan dipindahkan ke sampah.",
|
||||
color = Constants.AppColors.OnSurfaceVariant
|
||||
color = AppColors.OnSurfaceVariant
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
@ -71,7 +72,7 @@ fun CategoryCard(
|
||||
showDeleteConfirm = false
|
||||
},
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Constants.AppColors.Error
|
||||
containerColor = AppColors.Error
|
||||
)
|
||||
) {
|
||||
Text("Hapus", color = Color.White)
|
||||
@ -79,10 +80,10 @@ fun CategoryCard(
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { showDeleteConfirm = false }) {
|
||||
Text("Batal", color = Constants.AppColors.OnSurfaceVariant)
|
||||
Text("Batal", color = AppColors.OnSurfaceVariant)
|
||||
}
|
||||
},
|
||||
containerColor = Constants.AppColors.Surface,
|
||||
containerColor = AppColors.Surface,
|
||||
shape = RoundedCornerShape(Constants.Radius.Large.dp)
|
||||
)
|
||||
}
|
||||
@ -107,7 +108,7 @@ fun CategoryCard(
|
||||
.clickable(onClick = onClick),
|
||||
shape = RoundedCornerShape(Constants.Radius.Large.dp),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = Constants.AppColors.Surface
|
||||
containerColor = AppColors.Surface
|
||||
),
|
||||
elevation = CardDefaults.cardElevation(
|
||||
defaultElevation = Constants.Elevation.Small.dp
|
||||
@ -167,7 +168,7 @@ fun CategoryCard(
|
||||
Icon(
|
||||
Icons.Default.MoreVert,
|
||||
contentDescription = "Menu",
|
||||
tint = Constants.AppColors.OnSurfaceVariant,
|
||||
tint = AppColors.OnSurfaceVariant,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
@ -175,7 +176,7 @@ fun CategoryCard(
|
||||
DropdownMenu(
|
||||
expanded = showMenu,
|
||||
onDismissRequest = { showMenu = false },
|
||||
modifier = Modifier.background(Constants.AppColors.SurfaceElevated)
|
||||
modifier = Modifier.background(AppColors.SurfaceElevated)
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
@ -186,12 +187,12 @@ fun CategoryCard(
|
||||
Icon(
|
||||
Icons.Default.Edit,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Primary,
|
||||
tint = AppColors.Primary,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Text(
|
||||
"Edit Kategori",
|
||||
color = Constants.AppColors.OnSurface,
|
||||
color = AppColors.OnSurface,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
}
|
||||
@ -211,12 +212,12 @@ fun CategoryCard(
|
||||
Icon(
|
||||
Icons.Default.Delete,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.Error,
|
||||
tint = AppColors.Error,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Text(
|
||||
"Pindah ke Sampah",
|
||||
color = Constants.AppColors.OnSurface,
|
||||
color = AppColors.OnSurface,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
}
|
||||
@ -237,7 +238,7 @@ fun CategoryCard(
|
||||
category.name,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
fontSize = 18.sp
|
||||
)
|
||||
|
||||
@ -251,13 +252,13 @@ fun CategoryCard(
|
||||
Icon(
|
||||
Icons.Default.Description,
|
||||
contentDescription = null,
|
||||
tint = Constants.AppColors.OnSurfaceTertiary,
|
||||
tint = AppColors.OnSurfaceTertiary,
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
Text(
|
||||
"$noteCount catatan",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = Constants.AppColors.OnSurfaceTertiary,
|
||||
color = AppColors.OnSurfaceTertiary,
|
||||
fontSize = 13.sp
|
||||
)
|
||||
}
|
||||
@ -275,7 +276,7 @@ fun EditCategoryDialog(
|
||||
var name by remember { mutableStateOf(category.name) }
|
||||
var selectedGradient by remember {
|
||||
mutableStateOf(
|
||||
Constants.AppColors.CategoryColors.indexOfFirst {
|
||||
Constants.CategoryColors.indexOfFirst {
|
||||
it.first == category.gradientStart && it.second == category.gradientEnd
|
||||
}.takeIf { it >= 0 } ?: 0
|
||||
)
|
||||
@ -283,12 +284,12 @@ fun EditCategoryDialog(
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
containerColor = Constants.AppColors.Surface,
|
||||
containerColor = AppColors.Surface,
|
||||
shape = RoundedCornerShape(Constants.Radius.Large.dp),
|
||||
title = {
|
||||
Text(
|
||||
"Edit Kategori",
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
},
|
||||
@ -300,18 +301,18 @@ fun EditCategoryDialog(
|
||||
label = {
|
||||
Text(
|
||||
"Nama Kategori",
|
||||
color = Constants.AppColors.OnSurfaceVariant
|
||||
color = AppColors.OnSurfaceVariant
|
||||
)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = OutlinedTextFieldDefaults.colors(
|
||||
focusedTextColor = Constants.AppColors.OnBackground,
|
||||
unfocusedTextColor = Constants.AppColors.OnSurface,
|
||||
focusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = Constants.AppColors.SurfaceVariant,
|
||||
cursorColor = Constants.AppColors.Primary,
|
||||
focusedBorderColor = Constants.AppColors.Primary,
|
||||
unfocusedBorderColor = Constants.AppColors.Border
|
||||
focusedTextColor = AppColors.OnBackground,
|
||||
unfocusedTextColor = AppColors.OnSurface,
|
||||
focusedContainerColor = AppColors.SurfaceVariant,
|
||||
unfocusedContainerColor = AppColors.SurfaceVariant,
|
||||
cursorColor = AppColors.Primary,
|
||||
focusedBorderColor = AppColors.Primary,
|
||||
unfocusedBorderColor = AppColors.Border
|
||||
),
|
||||
shape = RoundedCornerShape(Constants.Radius.Medium.dp)
|
||||
)
|
||||
@ -321,20 +322,20 @@ fun EditCategoryDialog(
|
||||
Text(
|
||||
"Pilih Warna:",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Constants.AppColors.OnSurface,
|
||||
color = AppColors.OnSurface,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Constants.AppColors.CategoryColors.chunked(4).forEach { row ->
|
||||
Constants.CategoryColors.chunked(4).forEach { row ->
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
row.forEachIndexed { _, gradient ->
|
||||
val globalIndex = Constants.AppColors.CategoryColors.indexOf(gradient)
|
||||
val globalIndex = Constants.CategoryColors.indexOf(gradient)
|
||||
val isSelected = selectedGradient == globalIndex
|
||||
|
||||
Box(
|
||||
@ -376,13 +377,13 @@ fun EditCategoryDialog(
|
||||
Button(
|
||||
onClick = {
|
||||
if (name.isNotBlank()) {
|
||||
val gradient = Constants.AppColors.CategoryColors[selectedGradient]
|
||||
val gradient = Constants.CategoryColors[selectedGradient]
|
||||
onSave(name, gradient.first, gradient.second)
|
||||
}
|
||||
},
|
||||
enabled = name.isNotBlank(),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Constants.AppColors.Primary
|
||||
containerColor = AppColors.Primary
|
||||
)
|
||||
) {
|
||||
Text("Simpan", color = Color.White, fontWeight = FontWeight.Bold)
|
||||
@ -390,7 +391,7 @@ fun EditCategoryDialog(
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text("Batal", color = Constants.AppColors.OnSurfaceVariant)
|
||||
Text("Batal", color = AppColors.OnSurfaceVariant)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@ -20,6 +20,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.notesai.data.model.Note
|
||||
import com.example.notesai.util.AppColors
|
||||
import com.example.notesai.util.Constants
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
@ -51,7 +52,7 @@ fun NoteCard(
|
||||
.combinedClickable(onClick = onClick),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = Constants.AppColors.SurfaceVariant
|
||||
containerColor = AppColors.SurfaceVariant
|
||||
),
|
||||
elevation = CardDefaults.cardElevation(
|
||||
defaultElevation = 2.dp
|
||||
@ -73,7 +74,7 @@ fun NoteCard(
|
||||
note.title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Constants.AppColors.OnBackground,
|
||||
color = AppColors.OnBackground,
|
||||
modifier = Modifier.weight(1f),
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
@ -88,7 +89,7 @@ fun NoteCard(
|
||||
Icon(
|
||||
if (note.isPinned) Icons.Filled.Star else Icons.Outlined.StarBorder,
|
||||
contentDescription = "Pin",
|
||||
tint = if (note.isPinned) Constants.AppColors.Warning else Constants.AppColors.OnSurfaceVariant,
|
||||
tint = if (note.isPinned) AppColors.Warning else AppColors.OnSurfaceVariant,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -103,7 +104,7 @@ fun NoteCard(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
maxLines = 3,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = Constants.AppColors.OnSurfaceVariant,
|
||||
color = AppColors.OnSurfaceVariant,
|
||||
lineHeight = 20.sp,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
@ -114,7 +115,7 @@ fun NoteCard(
|
||||
Text(
|
||||
"Tidak ada deskripsi",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Constants.AppColors.OnSurfaceVariant.copy(alpha = 0.5f),
|
||||
color = AppColors.OnSurfaceVariant.copy(alpha = 0.5f),
|
||||
fontStyle = androidx.compose.ui.text.font.FontStyle.Italic,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
@ -124,7 +125,7 @@ fun NoteCard(
|
||||
|
||||
// Divider
|
||||
HorizontalDivider(
|
||||
color = Constants.AppColors.Divider,
|
||||
color = AppColors.Divider,
|
||||
thickness = 1.dp
|
||||
)
|
||||
|
||||
@ -139,7 +140,7 @@ fun NoteCard(
|
||||
Text(
|
||||
dateFormat.format(Date(note.timestamp)),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = Constants.AppColors.OnSurfaceTertiary,
|
||||
color = AppColors.OnSurfaceTertiary,
|
||||
fontSize = 12.sp
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
package com.example.notesai.util
|
||||
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
object Constants {
|
||||
@ -16,56 +19,68 @@ object Constants {
|
||||
const val MAX_CHAT_PREVIEW_LINES = 2
|
||||
const val GRID_COLUMNS = 2
|
||||
|
||||
// NEW MINIMALIST COLOR PALETTE
|
||||
object AppColors {
|
||||
// Backgrounds - Neutral Dark
|
||||
val Background = Color(0xFF0A0A0A) // Almost black
|
||||
val Surface = Color(0xFF141414) // Dark gray
|
||||
val SurfaceVariant = Color(0xFF1E1E1E) // Lighter dark gray
|
||||
val SurfaceElevated = Color(0xFF252525) // Elevated surface
|
||||
|
||||
// Primary Accent - Subtle Blue (minimalist)
|
||||
val Primary = Color(0xFF3B82F6) // Modern blue
|
||||
val PrimaryVariant = Color(0xFF60A5FA) // Light blue
|
||||
val PrimaryContainer = Color(0xFF1E3A8A) // Dark blue container
|
||||
|
||||
// Secondary Accent - Minimal use
|
||||
val Secondary = Color(0xFF8B5CF6) // Subtle purple
|
||||
val SecondaryVariant = Color(0xFFA78BFA) // Light purple
|
||||
|
||||
// Text Colors - High contrast for readability
|
||||
val OnBackground = Color(0xFFFFFFFF) // Pure white
|
||||
val OnSurface = Color(0xFFE5E5E5) // Off white
|
||||
val OnSurfaceVariant = Color(0xFF9CA3AF) // Gray text
|
||||
val OnSurfaceTertiary = Color(0xFF6B7280) // Muted gray
|
||||
|
||||
// Functional Colors
|
||||
val Success = Color(0xFF10B981) // Green
|
||||
val Error = Color(0xFFEF4444) // Red
|
||||
val Warning = Color(0xFFFBBF24) // Amber
|
||||
val Info = Color(0xFF3B82F6) // Blue
|
||||
|
||||
// Border & Dividers - Subtle
|
||||
val Border = Color(0xFF2A2A2A) // Subtle border
|
||||
val Divider = Color(0xFF1F1F1F) // Very subtle divider
|
||||
|
||||
// Overlay & Shadows
|
||||
// DARK THEME COLORS
|
||||
object DarkColors {
|
||||
val Background = Color(0xFF0A0A0A)
|
||||
val Surface = Color(0xFF141414)
|
||||
val SurfaceVariant = Color(0xFF1E1E1E)
|
||||
val SurfaceElevated = Color(0xFF252525)
|
||||
val Primary = Color(0xFF3B82F6)
|
||||
val PrimaryVariant = Color(0xFF60A5FA)
|
||||
val PrimaryContainer = Color(0xFF1E3A8A)
|
||||
val Secondary = Color(0xFF8B5CF6)
|
||||
val SecondaryVariant = Color(0xFFA78BFA)
|
||||
val OnBackground = Color(0xFFFFFFFF)
|
||||
val OnSurface = Color(0xFFE5E5E5)
|
||||
val OnSurfaceVariant = Color(0xFF9CA3AF)
|
||||
val OnSurfaceTertiary = Color(0xFF6B7280)
|
||||
val Success = Color(0xFF10B981)
|
||||
val Error = Color(0xFFEF4444)
|
||||
val Warning = Color(0xFFFBBF24)
|
||||
val Info = Color(0xFF3B82F6)
|
||||
val Border = Color(0xFF2A2A2A)
|
||||
val Divider = Color(0xFF1F1F1F)
|
||||
val Overlay = Color(0xFF000000).copy(alpha = 0.5f)
|
||||
val Shadow = Color(0xFF000000).copy(alpha = 0.3f)
|
||||
|
||||
// Category Colors - Minimalist Palette (subtle & muted)
|
||||
val CategoryColors = listOf(
|
||||
Pair(0xFF3B82F6L, 0xFF60A5FAL), // Blue gradient
|
||||
Pair(0xFF8B5CF6L, 0xFFA78BFAL), // Purple gradient
|
||||
Pair(0xFF10B981L, 0xFF34D399L), // Green gradient
|
||||
Pair(0xFFF59E0BL, 0xFFFBBF24L), // Amber gradient
|
||||
Pair(0xFFEF4444L, 0xFFF87171L), // Red gradient
|
||||
Pair(0xFF06B6D4L, 0xFF22D3EEL), // Cyan gradient
|
||||
Pair(0xFFEC4899L, 0xFFF472B6L), // Pink gradient
|
||||
Pair(0xFF6366F1L, 0xFF818CF8L) // Indigo gradient
|
||||
)
|
||||
}
|
||||
|
||||
// LIGHT THEME COLORS
|
||||
object LightColors {
|
||||
val Background = Color(0xFFF8F9FA)
|
||||
val Surface = Color(0xFFFFFFFF)
|
||||
val SurfaceVariant = Color(0xFFF1F3F5)
|
||||
val SurfaceElevated = Color(0xFFFFFFFF)
|
||||
val Primary = Color(0xFF3B82F6)
|
||||
val PrimaryVariant = Color(0xFF2563EB)
|
||||
val PrimaryContainer = Color(0xFFDCEEFF)
|
||||
val Secondary = Color(0xFF8B5CF6)
|
||||
val SecondaryVariant = Color(0xFF7C3AED)
|
||||
val OnBackground = Color(0xFF1F2937)
|
||||
val OnSurface = Color(0xFF374151)
|
||||
val OnSurfaceVariant = Color(0xFF6B7280)
|
||||
val OnSurfaceTertiary = Color(0xFF9CA3AF)
|
||||
val Success = Color(0xFF10B981)
|
||||
val Error = Color(0xFFEF4444)
|
||||
val Warning = Color(0xFFA16207)
|
||||
val Info = Color(0xFF3B82F6)
|
||||
val Border = Color(0xFFE5E7EB)
|
||||
val Divider = Color(0xFFF3F4F6)
|
||||
val Overlay = Color(0xFF000000).copy(alpha = 0.3f)
|
||||
val Shadow = Color(0xFF000000).copy(alpha = 0.1f)
|
||||
}
|
||||
|
||||
// Category Colors - Same for both themes
|
||||
val CategoryColors = listOf(
|
||||
Pair(0xFF3B82F6L, 0xFF60A5FAL), // Blue
|
||||
Pair(0xFF8B5CF6L, 0xFFA78BFAL), // Purple
|
||||
Pair(0xFF10B981L, 0xFF34D399L), // Green
|
||||
Pair(0xFFF59E0BL, 0xFFFBBF24L), // Amber
|
||||
Pair(0xFFEF4444L, 0xFFF87171L), // Red
|
||||
Pair(0xFF06B6D4L, 0xFF22D3EEL), // Cyan
|
||||
Pair(0xFFEC4899L, 0xFFF472B6L), // Pink
|
||||
Pair(0xFF6366F1L, 0xFF818CF8L) // Indigo
|
||||
)
|
||||
|
||||
// Animation Durations
|
||||
const val ANIMATION_DURATION_SHORT = 150
|
||||
const val ANIMATION_DURATION_MEDIUM = 300
|
||||
@ -73,7 +88,7 @@ object Constants {
|
||||
const val FADE_IN_DURATION = 200
|
||||
const val FADE_OUT_DURATION = 200
|
||||
|
||||
// Spacing System (8dp grid)
|
||||
// Spacing System
|
||||
object Spacing {
|
||||
const val ExtraSmall = 4
|
||||
const val Small = 8
|
||||
@ -100,4 +115,79 @@ object Constants {
|
||||
const val Large = 8
|
||||
const val ExtraLarge = 16
|
||||
}
|
||||
}
|
||||
|
||||
// REACTIVE APP COLORS - Using Compose State
|
||||
object AppColors {
|
||||
// Internal state
|
||||
private var _isDark by mutableStateOf(true)
|
||||
|
||||
// Public setter
|
||||
fun setTheme(isDark: Boolean) {
|
||||
_isDark = isDark
|
||||
}
|
||||
|
||||
// All colors are now reactive via mutableStateOf
|
||||
val Background: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Background else Constants.LightColors.Background
|
||||
|
||||
val Surface: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Surface else Constants.LightColors.Surface
|
||||
|
||||
val SurfaceVariant: Color
|
||||
get() = if (_isDark) Constants.DarkColors.SurfaceVariant else Constants.LightColors.SurfaceVariant
|
||||
|
||||
val SurfaceElevated: Color
|
||||
get() = if (_isDark) Constants.DarkColors.SurfaceElevated else Constants.LightColors.SurfaceElevated
|
||||
|
||||
val Primary: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Primary else Constants.LightColors.Primary
|
||||
|
||||
val PrimaryVariant: Color
|
||||
get() = if (_isDark) Constants.DarkColors.PrimaryVariant else Constants.LightColors.PrimaryVariant
|
||||
|
||||
val PrimaryContainer: Color
|
||||
get() = if (_isDark) Constants.DarkColors.PrimaryContainer else Constants.LightColors.PrimaryContainer
|
||||
|
||||
val Secondary: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Secondary else Constants.LightColors.Secondary
|
||||
|
||||
val SecondaryVariant: Color
|
||||
get() = if (_isDark) Constants.DarkColors.SecondaryVariant else Constants.LightColors.SecondaryVariant
|
||||
|
||||
val OnBackground: Color
|
||||
get() = if (_isDark) Constants.DarkColors.OnBackground else Constants.LightColors.OnBackground
|
||||
|
||||
val OnSurface: Color
|
||||
get() = if (_isDark) Constants.DarkColors.OnSurface else Constants.LightColors.OnSurface
|
||||
|
||||
val OnSurfaceVariant: Color
|
||||
get() = if (_isDark) Constants.DarkColors.OnSurfaceVariant else Constants.LightColors.OnSurfaceVariant
|
||||
|
||||
val OnSurfaceTertiary: Color
|
||||
get() = if (_isDark) Constants.DarkColors.OnSurfaceTertiary else Constants.LightColors.OnSurfaceTertiary
|
||||
|
||||
val Success: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Success else Constants.LightColors.Success
|
||||
|
||||
val Error: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Error else Constants.LightColors.Error
|
||||
|
||||
val Warning: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Warning else Constants.LightColors.Warning
|
||||
|
||||
val Info: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Info else Constants.LightColors.Info
|
||||
|
||||
val Border: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Border else Constants.LightColors.Border
|
||||
|
||||
val Divider: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Divider else Constants.LightColors.Divider
|
||||
|
||||
val Overlay: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Overlay else Constants.LightColors.Overlay
|
||||
|
||||
val Shadow: Color
|
||||
get() = if (_isDark) Constants.DarkColors.Shadow else Constants.LightColors.Shadow
|
||||
}
|
||||
@ -12,6 +12,10 @@ constraintlayout = "2.1.4"
|
||||
uiText = "1.10.0"
|
||||
material3 = "1.4.0"
|
||||
animationCore = "1.10.0"
|
||||
firebaseAnnotations = "17.0.0"
|
||||
firebaseFirestoreKtx = "26.0.2"
|
||||
uiGraphics = "1.10.0"
|
||||
roomCompiler = "2.8.4"
|
||||
|
||||
[libraries]
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
@ -25,6 +29,10 @@ androidx-constraintlayout = { group = "androidx.constraintlayout", name = "const
|
||||
androidx-ui-text = { group = "androidx.compose.ui", name = "ui-text", version.ref = "uiText" }
|
||||
androidx-material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" }
|
||||
androidx-animation-core = { group = "androidx.compose.animation", name = "animation-core", version.ref = "animationCore" }
|
||||
firebase-annotations = { group = "com.google.firebase", name = "firebase-annotations", version.ref = "firebaseAnnotations" }
|
||||
firebase-firestore-ktx = { group = "com.google.firebase", name = "firebase-firestore-ktx", version.ref = "firebaseFirestoreKtx" }
|
||||
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "uiGraphics" }
|
||||
androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "roomCompiler" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user