feat: Migrate UI theme system from hardcoded colors to Material3 dynamic theming
- Inject ThemePreferences into MainActivity and apply dynamic theme selection - Replace all hardcoded color references (DeepNavy, DarkNavy, CyanPrimary, TextPrimary, etc.) with MaterialTheme.colorScheme equivalents throughout AddLinkScreen and LoginScreen - Update component colors to use Material3 color roles (primary, onBackground, surfaceVariant, outline, etc.) - Migrate GlassCard, buttons, text fields, switches, and progress
This commit is contained in:
parent
80ab3009aa
commit
98f2ef2e7e
@ -8,18 +8,25 @@ import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.core.view.WindowCompat
|
||||
import com.shaarit.presentation.nav.AppNavGraph
|
||||
import com.shaarit.ui.theme.ShaarItTheme
|
||||
import com.shaarit.ui.theme.ThemePreferences
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
@Inject lateinit var themePreferences: ThemePreferences
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
// Install splash screen before super.onCreate
|
||||
installSplashScreen()
|
||||
@ -31,7 +38,8 @@ class MainActivity : ComponentActivity() {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
|
||||
setContent {
|
||||
ShaarItTheme {
|
||||
val currentTheme by themePreferences.currentTheme.collectAsState()
|
||||
ShaarItTheme(appTheme = currentTheme) {
|
||||
// A surface container using the 'background' color from the theme
|
||||
val context = LocalContext.current
|
||||
var shareUrl: String? = null
|
||||
|
||||
@ -34,8 +34,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import coil.compose.AsyncImage
|
||||
import com.shaarit.ui.components.*
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Purple
|
||||
import com.shaarit.ui.theme.Typography
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, androidx.compose.foundation.ExperimentalFoundationApi::class)
|
||||
@ -109,37 +108,37 @@ fun AddLinkScreen(
|
||||
AlertDialog(
|
||||
onDismissRequest = { viewModel.dismissConflict() },
|
||||
title = {
|
||||
Text("Lien déjà existant", fontWeight = FontWeight.Bold, color = TextPrimary)
|
||||
Text("Lien déjà existant", fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.onBackground)
|
||||
},
|
||||
text = {
|
||||
Column {
|
||||
Text("Un lien avec cette URL existe déjà:", color = TextSecondary)
|
||||
Text("Un lien avec cette URL existe déjà:", color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
conflict.existingTitle ?: "Sans titre",
|
||||
color = CyanPrimary,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(
|
||||
"Voulez-vous mettre à jour le lien existant?",
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = { viewModel.forceUpdateExistingLink() }) {
|
||||
Text("Mettre à jour", color = CyanPrimary)
|
||||
Text("Mettre à jour", color = MaterialTheme.colorScheme.primary)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { viewModel.dismissConflict() }) {
|
||||
Text("Annuler", color = TextMuted)
|
||||
Text("Annuler", color = MaterialTheme.colorScheme.outline)
|
||||
}
|
||||
},
|
||||
containerColor = CardBackground,
|
||||
titleContentColor = TextPrimary,
|
||||
textContentColor = TextSecondary
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
titleContentColor = MaterialTheme.colorScheme.onBackground,
|
||||
textContentColor = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
@ -147,7 +146,7 @@ fun AddLinkScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(
|
||||
brush = Brush.verticalGradient(colors = listOf(DeepNavy, DarkNavy))
|
||||
brush = Brush.verticalGradient(colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface))
|
||||
)
|
||||
) {
|
||||
// Contenu principal avec Scaffold
|
||||
@ -167,13 +166,13 @@ fun AddLinkScreen(
|
||||
Icon(
|
||||
Icons.Default.ArrowBack,
|
||||
contentDescription = "Retour",
|
||||
tint = TextPrimary
|
||||
tint = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = DeepNavy.copy(alpha = 0.9f),
|
||||
titleContentColor = TextPrimary
|
||||
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
|
||||
titleContentColor = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
)
|
||||
},
|
||||
@ -191,7 +190,7 @@ fun AddLinkScreen(
|
||||
// Content Type Selection (compact)
|
||||
GlassCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
glowColor = CyanPrimary
|
||||
glowColor = MaterialTheme.colorScheme.primary
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@ -236,14 +235,14 @@ fun AddLinkScreen(
|
||||
value = url,
|
||||
onValueChange = { viewModel.url.value = it },
|
||||
modifier = Modifier.weight(1f),
|
||||
placeholder = { Text("https://example.com", color = TextMuted) },
|
||||
placeholder = { Text("https://example.com", color = MaterialTheme.colorScheme.outline) },
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
|
||||
trailingIcon = {
|
||||
if (isExtractingMetadata) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(18.dp),
|
||||
color = CyanPrimary,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
}
|
||||
@ -288,14 +287,14 @@ fun AddLinkScreen(
|
||||
else -> Icons.Default.Web
|
||||
},
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = type,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -329,7 +328,7 @@ fun AddLinkScreen(
|
||||
Text(
|
||||
if (contentTypeSelection == ContentType.NOTE)
|
||||
"Titre de la note" else "Titre du lien",
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
},
|
||||
singleLine = true,
|
||||
@ -365,7 +364,7 @@ fun AddLinkScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Description,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Column {
|
||||
@ -374,13 +373,13 @@ fun AddLinkScreen(
|
||||
"Contenu" else "Description",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
if (contentTypeSelection == ContentType.NOTE) {
|
||||
Text(
|
||||
text = "Markdown supporté",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -397,7 +396,7 @@ fun AddLinkScreen(
|
||||
Icon(
|
||||
Icons.Default.Edit,
|
||||
contentDescription = "Éditer",
|
||||
tint = if (!showMarkdownPreview) CyanPrimary else TextMuted,
|
||||
tint = if (!showMarkdownPreview) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -408,7 +407,7 @@ fun AddLinkScreen(
|
||||
Icon(
|
||||
Icons.Default.Preview,
|
||||
contentDescription = "Aperçu",
|
||||
tint = if (showMarkdownPreview) CyanPrimary else TextMuted,
|
||||
tint = if (showMarkdownPreview) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -463,14 +462,14 @@ fun AddLinkScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Tag,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Text(
|
||||
text = "Tags",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
|
||||
@ -511,7 +510,7 @@ fun AddLinkScreen(
|
||||
}
|
||||
}
|
||||
},
|
||||
placeholder = { Text("Ajouter un tag...", color = TextMuted) },
|
||||
placeholder = { Text("Ajouter un tag...", color = MaterialTheme.colorScheme.outline) },
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(
|
||||
@ -537,7 +536,7 @@ fun AddLinkScreen(
|
||||
Icon(
|
||||
Icons.Default.Add,
|
||||
contentDescription = "Ajouter",
|
||||
tint = if (newTagInput.isNotBlank()) CyanPrimary else TextMuted
|
||||
tint = if (newTagInput.isNotBlank()) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -552,7 +551,7 @@ fun AddLinkScreen(
|
||||
Text(
|
||||
"Suggestions",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.padding(bottom = 8.dp)
|
||||
)
|
||||
LazyRow(
|
||||
@ -579,7 +578,7 @@ fun AddLinkScreen(
|
||||
Text(
|
||||
"Populaires",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.padding(bottom = 8.dp)
|
||||
)
|
||||
LazyRow(
|
||||
@ -617,16 +616,16 @@ fun AddLinkScreen(
|
||||
Text(
|
||||
if (isPrivate) "Seul vous pouvez voir" else "Visible par tous",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Switch(
|
||||
checked = isPrivate,
|
||||
onCheckedChange = { viewModel.isPrivate.value = it },
|
||||
colors = SwitchDefaults.colors(
|
||||
checkedThumbColor = CyanPrimary,
|
||||
checkedTrackColor = CyanPrimary.copy(alpha = 0.3f),
|
||||
uncheckedThumbColor = TextMuted,
|
||||
uncheckedTrackColor = SurfaceVariant
|
||||
checkedThumbColor = MaterialTheme.colorScheme.primary,
|
||||
checkedTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f),
|
||||
uncheckedThumbColor = MaterialTheme.colorScheme.outline,
|
||||
uncheckedTrackColor = MaterialTheme.colorScheme.outlineVariant
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -652,8 +651,8 @@ fun AddLinkScreen(
|
||||
if (uiState is AddLinkUiState.Loading) {
|
||||
LinearProgressIndicator(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
color = CyanPrimary,
|
||||
trackColor = SurfaceVariant
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
trackColor = MaterialTheme.colorScheme.outlineVariant
|
||||
)
|
||||
}
|
||||
|
||||
@ -685,8 +684,8 @@ private fun ContentTypeButton(
|
||||
Surface(
|
||||
onClick = onClick,
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
color = if (isSelected) CyanPrimary.copy(alpha = 0.15f) else CardBackgroundElevated,
|
||||
border = if (isSelected) androidx.compose.foundation.BorderStroke(1.5.dp, CyanPrimary) else null,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.15f) else MaterialTheme.colorScheme.primaryContainer,
|
||||
border = if (isSelected) androidx.compose.foundation.BorderStroke(1.5.dp, MaterialTheme.colorScheme.primary) else null,
|
||||
modifier = modifier
|
||||
) {
|
||||
Row(
|
||||
@ -697,14 +696,14 @@ private fun ContentTypeButton(
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = if (isSelected) CyanPrimary else TextSecondary,
|
||||
tint = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = if (isSelected) CyanPrimary else TextPrimary,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground,
|
||||
fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal
|
||||
)
|
||||
}
|
||||
@ -731,7 +730,7 @@ private fun CompactFieldCard(
|
||||
|
||||
GlassCard(
|
||||
modifier = finalModifier,
|
||||
glowColor = CyanPrimary.copy(alpha = 0.3f)
|
||||
glowColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f)
|
||||
) {
|
||||
Column {
|
||||
Row(
|
||||
@ -742,13 +741,13 @@ private fun CompactFieldCard(
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = TextSecondary,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
}
|
||||
@ -763,13 +762,13 @@ private fun CompactFieldCard(
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun compactTextFieldColors() = OutlinedTextFieldDefaults.colors(
|
||||
focusedBorderColor = CyanPrimary,
|
||||
unfocusedBorderColor = SurfaceVariant,
|
||||
focusedLabelColor = CyanPrimary,
|
||||
unfocusedLabelColor = TextSecondary,
|
||||
cursorColor = CyanPrimary,
|
||||
focusedContainerColor = CardBackground.copy(alpha = 0.3f),
|
||||
unfocusedContainerColor = CardBackground.copy(alpha = 0.2f)
|
||||
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
||||
unfocusedBorderColor = MaterialTheme.colorScheme.outlineVariant,
|
||||
focusedLabelColor = MaterialTheme.colorScheme.primary,
|
||||
unfocusedLabelColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
cursorColor = MaterialTheme.colorScheme.primary,
|
||||
focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f),
|
||||
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.2f)
|
||||
)
|
||||
|
||||
/**
|
||||
@ -797,8 +796,8 @@ private fun AiMagicButton(
|
||||
onClick = onClick,
|
||||
enabled = enabled && !isLoading,
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
color = if (enabled) Purple.copy(alpha = if (isLoading) shimmerAlpha * 0.3f else 0.15f) else SurfaceVariant,
|
||||
border = if (enabled) androidx.compose.foundation.BorderStroke(1.5.dp, Purple) else null,
|
||||
color = if (enabled) MaterialTheme.colorScheme.tertiary.copy(alpha = if (isLoading) shimmerAlpha * 0.3f else 0.15f) else MaterialTheme.colorScheme.outlineVariant,
|
||||
border = if (enabled) androidx.compose.foundation.BorderStroke(1.5.dp, MaterialTheme.colorScheme.tertiary) else null,
|
||||
modifier = modifier.size(48.dp)
|
||||
) {
|
||||
Box(
|
||||
@ -808,14 +807,14 @@ private fun AiMagicButton(
|
||||
if (isLoading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
color = Purple,
|
||||
color = MaterialTheme.colorScheme.tertiary,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.AutoAwesome,
|
||||
contentDescription = "Magie IA",
|
||||
tint = if (enabled) Purple else TextMuted,
|
||||
tint = if (enabled) MaterialTheme.colorScheme.tertiary else MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(22.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.shaarit.ui.components.GlassCard
|
||||
import com.shaarit.ui.components.GradientButton
|
||||
import com.shaarit.ui.components.PremiumTextField
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Typography
|
||||
|
||||
@Composable
|
||||
fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltViewModel()) {
|
||||
@ -58,7 +58,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
|
||||
.background(
|
||||
brush =
|
||||
Brush.verticalGradient(
|
||||
colors = listOf(DeepNavy, DarkNavy)
|
||||
colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface)
|
||||
)
|
||||
)
|
||||
) {
|
||||
@ -71,7 +71,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
|
||||
Brush.radialGradient(
|
||||
colors =
|
||||
listOf(
|
||||
CyanPrimary.copy(
|
||||
MaterialTheme.colorScheme.primary.copy(
|
||||
alpha =
|
||||
backgroundAlpha
|
||||
),
|
||||
@ -110,13 +110,13 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
|
||||
text = "ShaarIt",
|
||||
style = MaterialTheme.typography.displayMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
text = "Your personal bookmark manager",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = TextSecondary,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
@ -131,7 +131,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
|
||||
text = "Connect to Shaarli",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
|
||||
PremiumTextField(
|
||||
@ -154,7 +154,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
|
||||
Icon(
|
||||
Icons.Default.Lock,
|
||||
contentDescription = null,
|
||||
tint = TextMuted
|
||||
tint = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
},
|
||||
trailingIcon = {
|
||||
@ -162,7 +162,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
|
||||
Text(
|
||||
if (showSecret) "Hide" else "Show",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -174,7 +174,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
contentAlignment = Alignment.Center
|
||||
) { CircularProgressIndicator(color = CyanPrimary) }
|
||||
) { CircularProgressIndicator(color = MaterialTheme.colorScheme.primary) }
|
||||
} else {
|
||||
GradientButton(
|
||||
text = "Connect",
|
||||
@ -192,7 +192,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
|
||||
text =
|
||||
"Find your API secret in Shaarli's\n\"Tools\" → \"Configure your Shaarli\"",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.alpha(0.7f)
|
||||
)
|
||||
|
||||
@ -27,7 +27,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.shaarit.ui.components.GlassCard
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Typography
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@ -47,7 +47,7 @@ fun CollectionsScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(
|
||||
brush = Brush.verticalGradient(colors = listOf(DeepNavy, DarkNavy))
|
||||
brush = Brush.verticalGradient(colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface))
|
||||
)
|
||||
) {
|
||||
Scaffold(
|
||||
@ -65,7 +65,7 @@ fun CollectionsScreen(
|
||||
Icon(
|
||||
Icons.Default.ArrowBack,
|
||||
contentDescription = "Retour",
|
||||
tint = TextPrimary
|
||||
tint = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -74,13 +74,13 @@ fun CollectionsScreen(
|
||||
Icon(
|
||||
Icons.Default.Add,
|
||||
contentDescription = "Nouvelle collection",
|
||||
tint = CyanPrimary
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = DeepNavy.copy(alpha = 0.9f),
|
||||
titleContentColor = TextPrimary
|
||||
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
|
||||
titleContentColor = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
)
|
||||
},
|
||||
@ -88,8 +88,8 @@ fun CollectionsScreen(
|
||||
floatingActionButton = {
|
||||
FloatingActionButton(
|
||||
onClick = { showCreateDialog = true },
|
||||
containerColor = CyanPrimary,
|
||||
contentColor = DeepNavy
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
contentColor = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
Icon(Icons.Default.Add, contentDescription = "Nouvelle collection")
|
||||
}
|
||||
@ -103,7 +103,7 @@ fun CollectionsScreen(
|
||||
if (isLoading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
color = CyanPrimary
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
} else if (collections.isEmpty()) {
|
||||
EmptyCollectionsView(onCreateClick = { showCreateDialog = true })
|
||||
@ -170,7 +170,7 @@ fun CollectionsScreen(
|
||||
showDeleteConfirm = null
|
||||
},
|
||||
colors = ButtonDefaults.textButtonColors(
|
||||
contentColor = ErrorRed
|
||||
contentColor = MaterialTheme.colorScheme.error
|
||||
)
|
||||
) {
|
||||
Text("Supprimer")
|
||||
@ -181,9 +181,9 @@ fun CollectionsScreen(
|
||||
Text("Annuler")
|
||||
}
|
||||
},
|
||||
containerColor = CardBackground,
|
||||
titleContentColor = TextPrimary,
|
||||
textContentColor = TextSecondary
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
titleContentColor = MaterialTheme.colorScheme.onBackground,
|
||||
textContentColor = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -226,7 +226,7 @@ private fun CollectionCard(
|
||||
Icon(
|
||||
imageVector = Icons.Default.AutoAwesome,
|
||||
contentDescription = "Collection intelligente",
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
@ -238,7 +238,7 @@ private fun CollectionCard(
|
||||
text = collection.name,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = TextPrimary,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
@ -248,7 +248,7 @@ private fun CollectionCard(
|
||||
Text(
|
||||
text = desc,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = TextSecondary,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.padding(top = 4.dp)
|
||||
@ -260,7 +260,7 @@ private fun CollectionCard(
|
||||
Text(
|
||||
text = "${collection.linkCount} lien${if (collection.linkCount > 1) "s" else ""}",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = CyanPrimary,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.padding(top = 8.dp)
|
||||
)
|
||||
}
|
||||
@ -279,7 +279,7 @@ private fun CollectionCard(
|
||||
Icon(
|
||||
imageVector = Icons.Default.MoreVert,
|
||||
contentDescription = "Options",
|
||||
tint = TextSecondary,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
@ -287,7 +287,7 @@ private fun CollectionCard(
|
||||
DropdownMenu(
|
||||
expanded = showMenu,
|
||||
onDismissRequest = { showMenu = false },
|
||||
modifier = Modifier.background(CardBackground)
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.surfaceVariant)
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
@ -298,10 +298,10 @@ private fun CollectionCard(
|
||||
Icon(
|
||||
Icons.Default.Edit,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Text("Modifier", color = TextPrimary)
|
||||
Text("Modifier", color = MaterialTheme.colorScheme.onBackground)
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
@ -318,10 +318,10 @@ private fun CollectionCard(
|
||||
Icon(
|
||||
Icons.Default.Delete,
|
||||
contentDescription = null,
|
||||
tint = ErrorRed,
|
||||
tint = MaterialTheme.colorScheme.error,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Text("Supprimer", color = ErrorRed)
|
||||
Text("Supprimer", color = MaterialTheme.colorScheme.error)
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
@ -347,7 +347,7 @@ private fun EmptyCollectionsView(onCreateClick: () -> Unit) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.FolderOpen,
|
||||
contentDescription = null,
|
||||
tint = TextMuted,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(80.dp)
|
||||
)
|
||||
|
||||
@ -357,7 +357,7 @@ private fun EmptyCollectionsView(onCreateClick: () -> Unit) {
|
||||
text = "Aucune collection",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
@ -365,7 +365,7 @@ private fun EmptyCollectionsView(onCreateClick: () -> Unit) {
|
||||
Text(
|
||||
text = "Créez des collections pour organiser vos liens par thème",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
textAlign = androidx.compose.ui.text.style.TextAlign.Center
|
||||
)
|
||||
|
||||
@ -374,8 +374,8 @@ private fun EmptyCollectionsView(onCreateClick: () -> Unit) {
|
||||
Button(
|
||||
onClick = onCreateClick,
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = CyanPrimary,
|
||||
contentColor = DeepNavy
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
contentColor = MaterialTheme.colorScheme.background
|
||||
)
|
||||
) {
|
||||
Icon(Icons.Default.Add, contentDescription = null)
|
||||
@ -443,11 +443,11 @@ private fun CollectionDialogContent(
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
containerColor = CardBackground,
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
title = {
|
||||
Text(
|
||||
title,
|
||||
color = TextPrimary,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
},
|
||||
@ -463,14 +463,14 @@ private fun CollectionDialogContent(
|
||||
OutlinedTextField(
|
||||
value = name,
|
||||
onValueChange = { name = it },
|
||||
label = { Text("Nom", color = TextSecondary) },
|
||||
label = { Text("Nom", color = MaterialTheme.colorScheme.onSurfaceVariant) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = OutlinedTextFieldDefaults.colors(
|
||||
focusedBorderColor = CyanPrimary,
|
||||
unfocusedBorderColor = TextMuted,
|
||||
focusedTextColor = TextPrimary,
|
||||
unfocusedTextColor = TextPrimary
|
||||
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
||||
unfocusedBorderColor = MaterialTheme.colorScheme.outline,
|
||||
focusedTextColor = MaterialTheme.colorScheme.onBackground,
|
||||
unfocusedTextColor = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
)
|
||||
|
||||
@ -478,15 +478,15 @@ private fun CollectionDialogContent(
|
||||
OutlinedTextField(
|
||||
value = description,
|
||||
onValueChange = { description = it },
|
||||
label = { Text("Description (optionnel)", color = TextSecondary) },
|
||||
label = { Text("Description (optionnel)", color = MaterialTheme.colorScheme.onSurfaceVariant) },
|
||||
minLines = 2,
|
||||
maxLines = 3,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = OutlinedTextFieldDefaults.colors(
|
||||
focusedBorderColor = CyanPrimary,
|
||||
unfocusedBorderColor = TextMuted,
|
||||
focusedTextColor = TextPrimary,
|
||||
unfocusedTextColor = TextPrimary
|
||||
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
||||
unfocusedBorderColor = MaterialTheme.colorScheme.outline,
|
||||
focusedTextColor = MaterialTheme.colorScheme.onBackground,
|
||||
unfocusedTextColor = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
)
|
||||
|
||||
@ -494,7 +494,7 @@ private fun CollectionDialogContent(
|
||||
Text(
|
||||
"Icône",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
@ -507,12 +507,12 @@ private fun CollectionDialogContent(
|
||||
.size(44.dp)
|
||||
.clip(RoundedCornerShape(10.dp))
|
||||
.background(
|
||||
if (isSelected) CyanPrimary.copy(alpha = 0.2f)
|
||||
else CardBackgroundElevated
|
||||
if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.2f)
|
||||
else MaterialTheme.colorScheme.surfaceVariant
|
||||
)
|
||||
.border(
|
||||
width = if (isSelected) 2.dp else 0.dp,
|
||||
color = if (isSelected) CyanPrimary else androidx.compose.ui.graphics.Color.Transparent,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
|
||||
shape = RoundedCornerShape(10.dp)
|
||||
)
|
||||
.clickable { selectedIcon = icon },
|
||||
@ -527,10 +527,10 @@ private fun CollectionDialogContent(
|
||||
Card(
|
||||
onClick = { isSmart = !isSmart },
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = if (isSmart) CyanPrimary.copy(alpha = 0.1f) else CardBackgroundElevated
|
||||
containerColor = if (isSmart) MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) else MaterialTheme.colorScheme.primaryContainer
|
||||
),
|
||||
border = if (isSmart) {
|
||||
androidx.compose.foundation.BorderStroke(1.dp, CyanPrimary.copy(alpha = 0.3f))
|
||||
androidx.compose.foundation.BorderStroke(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.3f))
|
||||
} else null,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
@ -548,19 +548,19 @@ private fun CollectionDialogContent(
|
||||
Icon(
|
||||
imageVector = Icons.Default.AutoAwesome,
|
||||
contentDescription = null,
|
||||
tint = if (isSmart) CyanPrimary else TextSecondary
|
||||
tint = if (isSmart) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
"Collection intelligente",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextPrimary,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
Text(
|
||||
"Remplie automatiquement selon les tags sélectionnés",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -568,8 +568,8 @@ private fun CollectionDialogContent(
|
||||
checked = isSmart,
|
||||
onCheckedChange = { isSmart = it },
|
||||
colors = SwitchDefaults.colors(
|
||||
checkedThumbColor = CyanPrimary,
|
||||
checkedTrackColor = CyanPrimary.copy(alpha = 0.5f)
|
||||
checkedThumbColor = MaterialTheme.colorScheme.primary,
|
||||
checkedTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.5f)
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -581,7 +581,7 @@ private fun CollectionDialogContent(
|
||||
Text(
|
||||
"Tags sélectionnés (${selectedTags.size})",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
FlowRow(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@ -608,22 +608,22 @@ private fun CollectionDialogContent(
|
||||
tagSearch = it
|
||||
showTagDropdown = it.isNotBlank() || tags.isNotEmpty()
|
||||
},
|
||||
label = { Text("Ajouter des tags...", color = TextSecondary) },
|
||||
label = { Text("Ajouter des tags...", color = MaterialTheme.colorScheme.onSurfaceVariant) },
|
||||
singleLine = true,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.menuAnchor(),
|
||||
colors = OutlinedTextFieldDefaults.colors(
|
||||
focusedBorderColor = CyanPrimary,
|
||||
unfocusedBorderColor = TextMuted,
|
||||
focusedTextColor = TextPrimary,
|
||||
unfocusedTextColor = TextPrimary
|
||||
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
||||
unfocusedBorderColor = MaterialTheme.colorScheme.outline,
|
||||
focusedTextColor = MaterialTheme.colorScheme.onBackground,
|
||||
unfocusedTextColor = MaterialTheme.colorScheme.onBackground
|
||||
),
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
imageVector = if (showTagDropdown) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
|
||||
contentDescription = null,
|
||||
tint = TextSecondary
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -643,7 +643,7 @@ private fun CollectionDialogContent(
|
||||
expanded = showTagDropdown,
|
||||
onDismissRequest = { showTagDropdown = false },
|
||||
modifier = Modifier
|
||||
.background(CardBackgroundElevated)
|
||||
.background(MaterialTheme.colorScheme.primaryContainer)
|
||||
.heightIn(max = 250.dp)
|
||||
) {
|
||||
availableTags.forEach { tag ->
|
||||
@ -651,7 +651,7 @@ private fun CollectionDialogContent(
|
||||
text = {
|
||||
Text(
|
||||
"#$tag",
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
@ -663,7 +663,7 @@ private fun CollectionDialogContent(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Add,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -683,7 +683,7 @@ private fun CollectionDialogContent(
|
||||
Text(
|
||||
"Tags populaires",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
FlowRow(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@ -709,8 +709,8 @@ private fun CollectionDialogContent(
|
||||
},
|
||||
enabled = name.isNotBlank() && (!isSmart || selectedTags.isNotEmpty()),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = CyanPrimary,
|
||||
contentColor = DeepNavy
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
contentColor = MaterialTheme.colorScheme.background
|
||||
)
|
||||
) {
|
||||
Text(if (isEdit) "Enregistrer" else "Créer")
|
||||
@ -718,7 +718,7 @@ private fun CollectionDialogContent(
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text("Annuler", color = TextSecondary)
|
||||
Text("Annuler", color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -731,8 +731,8 @@ private fun SelectedTagChip(
|
||||
) {
|
||||
Surface(
|
||||
shape = MaterialTheme.shapes.small,
|
||||
color = CyanPrimary.copy(alpha = 0.2f),
|
||||
border = androidx.compose.foundation.BorderStroke(1.dp, CyanPrimary.copy(alpha = 0.5f))
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.2f),
|
||||
border = androidx.compose.foundation.BorderStroke(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.5f))
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
@ -741,7 +741,7 @@ private fun SelectedTagChip(
|
||||
Text(
|
||||
text = "#$tag",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = CyanLight
|
||||
color = MaterialTheme.colorScheme.tertiary
|
||||
)
|
||||
IconButton(
|
||||
onClick = onRemove,
|
||||
@ -750,7 +750,7 @@ private fun SelectedTagChip(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = "Retirer",
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
@ -766,7 +766,7 @@ private fun AvailableTagChip(
|
||||
Surface(
|
||||
onClick = onClick,
|
||||
shape = MaterialTheme.shapes.small,
|
||||
color = CardBackground
|
||||
color = MaterialTheme.colorScheme.surfaceVariant
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
@ -775,14 +775,14 @@ private fun AvailableTagChip(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Add,
|
||||
contentDescription = null,
|
||||
tint = TextMuted,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(
|
||||
text = "#$tag",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.paging.LoadState
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.shaarit.presentation.feed.ListViewItem
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Typography
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@ -46,7 +46,7 @@ fun DeadLinksScreen(
|
||||
.fillMaxSize()
|
||||
.background(
|
||||
brush = Brush.verticalGradient(
|
||||
colors = listOf(DeepNavy, DarkNavy)
|
||||
colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface)
|
||||
)
|
||||
)
|
||||
) {
|
||||
@ -59,7 +59,7 @@ fun DeadLinksScreen(
|
||||
if (isSelectionMode) "${selectedLinkIds.size} sélectionné(s)" else "Liens inaccessibles",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
@ -73,7 +73,7 @@ fun DeadLinksScreen(
|
||||
Icon(
|
||||
if (isSelectionMode) Icons.Default.Close else Icons.Default.ArrowBack,
|
||||
contentDescription = if (isSelectionMode) "Annuler" else "Retour",
|
||||
tint = TextPrimary
|
||||
tint = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -87,14 +87,14 @@ fun DeadLinksScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.CheckCircle,
|
||||
contentDescription = "Exclure de la vérification",
|
||||
tint = SuccessGreen
|
||||
tint = Color(0xFF10B981)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = DeepNavy.copy(alpha = 0.9f),
|
||||
titleContentColor = TextPrimary
|
||||
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
|
||||
titleContentColor = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
)
|
||||
},
|
||||
@ -107,7 +107,7 @@ fun DeadLinksScreen(
|
||||
) {
|
||||
if (pagingItems.loadState.refresh is LoadState.Loading && pagingItems.itemCount == 0) {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator(color = CyanPrimary)
|
||||
CircularProgressIndicator(color = MaterialTheme.colorScheme.primary)
|
||||
}
|
||||
} else if (pagingItems.itemCount == 0) {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
@ -115,19 +115,19 @@ fun DeadLinksScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.BrokenImage,
|
||||
contentDescription = null,
|
||||
tint = TextMuted,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(64.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(
|
||||
"Aucun lien mort détecté",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Tout semble fonctionner !",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -198,7 +198,7 @@ private fun DeadLinkItem(
|
||||
onLongClick = onLongClick
|
||||
),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = if (isSelected) CyanPrimary.copy(alpha = 0.1f) else CardBackground
|
||||
containerColor = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) else MaterialTheme.colorScheme.surfaceVariant
|
||||
)
|
||||
) {
|
||||
ListViewItem(
|
||||
|
||||
@ -34,8 +34,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import coil.compose.AsyncImage
|
||||
import com.shaarit.presentation.add.ContentType
|
||||
import com.shaarit.ui.components.*
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Purple
|
||||
import com.shaarit.ui.theme.Typography
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, androidx.compose.foundation.ExperimentalFoundationApi::class)
|
||||
@ -107,7 +106,7 @@ fun EditLinkScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(
|
||||
brush = Brush.verticalGradient(colors = listOf(DeepNavy, DarkNavy))
|
||||
brush = Brush.verticalGradient(colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface))
|
||||
)
|
||||
) {
|
||||
Scaffold(
|
||||
@ -126,13 +125,13 @@ fun EditLinkScreen(
|
||||
Icon(
|
||||
Icons.Default.ArrowBack,
|
||||
contentDescription = "Retour",
|
||||
tint = TextPrimary
|
||||
tint = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = DeepNavy.copy(alpha = 0.9f),
|
||||
titleContentColor = TextPrimary
|
||||
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
|
||||
titleContentColor = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
)
|
||||
},
|
||||
@ -147,11 +146,11 @@ fun EditLinkScreen(
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
CircularProgressIndicator(color = CyanPrimary)
|
||||
CircularProgressIndicator(color = MaterialTheme.colorScheme.primary)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(
|
||||
"Chargement...",
|
||||
color = TextSecondary,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
@ -170,7 +169,7 @@ fun EditLinkScreen(
|
||||
// Content Type Selection (compact)
|
||||
GlassCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
glowColor = CyanPrimary
|
||||
glowColor = MaterialTheme.colorScheme.primary
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@ -215,7 +214,7 @@ fun EditLinkScreen(
|
||||
value = url,
|
||||
onValueChange = { viewModel.url.value = it },
|
||||
modifier = Modifier.weight(1f),
|
||||
placeholder = { Text("https://example.com", color = TextMuted) },
|
||||
placeholder = { Text("https://example.com", color = MaterialTheme.colorScheme.outline) },
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
|
||||
colors = compactTextFieldColors(),
|
||||
@ -230,21 +229,21 @@ fun EditLinkScreen(
|
||||
modifier = Modifier
|
||||
.size(48.dp) // Même taille que AiMagicButton
|
||||
.background(
|
||||
color = SurfaceVariant.copy(alpha = 0.5f),
|
||||
color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
)
|
||||
) {
|
||||
if (isExtractingMetadata) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
color = TextSecondary,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
Icons.Default.Refresh,
|
||||
contentDescription = "Récupérer infos classique",
|
||||
tint = TextSecondary
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -272,7 +271,7 @@ fun EditLinkScreen(
|
||||
Text(
|
||||
if (contentType == ContentType.NOTE)
|
||||
"Titre de la note" else "Titre du lien",
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
},
|
||||
singleLine = true,
|
||||
@ -308,7 +307,7 @@ fun EditLinkScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Description,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Column {
|
||||
@ -317,13 +316,13 @@ fun EditLinkScreen(
|
||||
"Contenu" else "Description",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
if (contentType == ContentType.NOTE) {
|
||||
Text(
|
||||
text = "Markdown supporté",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -340,7 +339,7 @@ fun EditLinkScreen(
|
||||
Icon(
|
||||
Icons.Default.Edit,
|
||||
contentDescription = "Éditer",
|
||||
tint = if (!showMarkdownPreview) CyanPrimary else TextMuted,
|
||||
tint = if (!showMarkdownPreview) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -351,7 +350,7 @@ fun EditLinkScreen(
|
||||
Icon(
|
||||
Icons.Default.Preview,
|
||||
contentDescription = "Aperçu",
|
||||
tint = if (showMarkdownPreview) CyanPrimary else TextMuted,
|
||||
tint = if (showMarkdownPreview) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -406,14 +405,14 @@ fun EditLinkScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Tag,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Text(
|
||||
text = "Tags",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
|
||||
@ -454,7 +453,7 @@ fun EditLinkScreen(
|
||||
}
|
||||
}
|
||||
},
|
||||
placeholder = { Text("Ajouter un tag...", color = TextMuted) },
|
||||
placeholder = { Text("Ajouter un tag...", color = MaterialTheme.colorScheme.outline) },
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(
|
||||
@ -480,7 +479,7 @@ fun EditLinkScreen(
|
||||
Icon(
|
||||
Icons.Default.Add,
|
||||
contentDescription = "Ajouter",
|
||||
tint = if (newTagInput.isNotBlank()) CyanPrimary else TextMuted
|
||||
tint = if (newTagInput.isNotBlank()) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
|
||||
@ -492,23 +491,23 @@ fun EditLinkScreen(
|
||||
.size(40.dp)
|
||||
.background(
|
||||
color = if (aiTagsState is AiEnrichmentState.Loading)
|
||||
SurfaceVariant.copy(alpha = 0.5f)
|
||||
MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f)
|
||||
else
|
||||
CyanPrimary.copy(alpha = 0.1f),
|
||||
MaterialTheme.colorScheme.primary.copy(alpha = 0.1f),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
)
|
||||
) {
|
||||
if (aiTagsState is AiEnrichmentState.Loading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
color = CyanPrimary,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
Icons.Outlined.AutoAwesome,
|
||||
contentDescription = "Générer tags IA",
|
||||
tint = CyanPrimary
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -524,7 +523,7 @@ fun EditLinkScreen(
|
||||
Text(
|
||||
"Suggestions",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.padding(bottom = 8.dp)
|
||||
)
|
||||
LazyRow(
|
||||
@ -551,7 +550,7 @@ fun EditLinkScreen(
|
||||
Text(
|
||||
"Populaires",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.padding(bottom = 8.dp)
|
||||
)
|
||||
LazyRow(
|
||||
@ -589,16 +588,16 @@ fun EditLinkScreen(
|
||||
Text(
|
||||
if (isPrivate) "Seul vous pouvez voir" else "Visible par tous",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Switch(
|
||||
checked = isPrivate,
|
||||
onCheckedChange = { viewModel.isPrivate.value = it },
|
||||
colors = SwitchDefaults.colors(
|
||||
checkedThumbColor = CyanPrimary,
|
||||
checkedTrackColor = CyanPrimary.copy(alpha = 0.3f),
|
||||
uncheckedThumbColor = TextMuted,
|
||||
uncheckedTrackColor = SurfaceVariant
|
||||
checkedThumbColor = MaterialTheme.colorScheme.primary,
|
||||
checkedTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f),
|
||||
uncheckedThumbColor = MaterialTheme.colorScheme.outline,
|
||||
uncheckedTrackColor = MaterialTheme.colorScheme.outlineVariant
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -624,8 +623,8 @@ fun EditLinkScreen(
|
||||
if (uiState is EditLinkUiState.Saving) {
|
||||
LinearProgressIndicator(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
color = CyanPrimary,
|
||||
trackColor = SurfaceVariant
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
trackColor = MaterialTheme.colorScheme.outlineVariant
|
||||
)
|
||||
}
|
||||
|
||||
@ -659,8 +658,8 @@ private fun ContentTypeButton(
|
||||
Surface(
|
||||
onClick = onClick,
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
color = if (isSelected) CyanPrimary.copy(alpha = 0.15f) else CardBackgroundElevated,
|
||||
border = if (isSelected) androidx.compose.foundation.BorderStroke(1.5.dp, CyanPrimary) else null,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.15f) else MaterialTheme.colorScheme.primaryContainer,
|
||||
border = if (isSelected) androidx.compose.foundation.BorderStroke(1.5.dp, MaterialTheme.colorScheme.primary) else null,
|
||||
modifier = modifier
|
||||
) {
|
||||
Row(
|
||||
@ -671,14 +670,14 @@ private fun ContentTypeButton(
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = if (isSelected) CyanPrimary else TextSecondary,
|
||||
tint = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = if (isSelected) CyanPrimary else TextPrimary,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground,
|
||||
fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal
|
||||
)
|
||||
}
|
||||
@ -705,7 +704,7 @@ private fun CompactFieldCard(
|
||||
|
||||
GlassCard(
|
||||
modifier = finalModifier,
|
||||
glowColor = CyanPrimary.copy(alpha = 0.3f)
|
||||
glowColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f)
|
||||
) {
|
||||
Column {
|
||||
Row(
|
||||
@ -716,13 +715,13 @@ private fun CompactFieldCard(
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = TextSecondary,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
}
|
||||
@ -737,13 +736,13 @@ private fun CompactFieldCard(
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun compactTextFieldColors() = OutlinedTextFieldDefaults.colors(
|
||||
focusedBorderColor = CyanPrimary,
|
||||
unfocusedBorderColor = SurfaceVariant,
|
||||
focusedLabelColor = CyanPrimary,
|
||||
unfocusedLabelColor = TextSecondary,
|
||||
cursorColor = CyanPrimary,
|
||||
focusedContainerColor = CardBackground.copy(alpha = 0.3f),
|
||||
unfocusedContainerColor = CardBackground.copy(alpha = 0.2f)
|
||||
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
||||
unfocusedBorderColor = MaterialTheme.colorScheme.outlineVariant,
|
||||
focusedLabelColor = MaterialTheme.colorScheme.primary,
|
||||
unfocusedLabelColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
cursorColor = MaterialTheme.colorScheme.primary,
|
||||
focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f),
|
||||
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.2f)
|
||||
)
|
||||
|
||||
/**
|
||||
@ -771,8 +770,8 @@ private fun AiMagicButton(
|
||||
onClick = onClick,
|
||||
enabled = enabled && !isLoading,
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
color = if (enabled) Purple.copy(alpha = if (isLoading) shimmerAlpha * 0.3f else 0.15f) else SurfaceVariant,
|
||||
border = if (enabled) androidx.compose.foundation.BorderStroke(1.5.dp, Purple) else null,
|
||||
color = if (enabled) MaterialTheme.colorScheme.tertiary.copy(alpha = if (isLoading) shimmerAlpha * 0.3f else 0.15f) else MaterialTheme.colorScheme.outlineVariant,
|
||||
border = if (enabled) androidx.compose.foundation.BorderStroke(1.5.dp, MaterialTheme.colorScheme.tertiary) else null,
|
||||
modifier = modifier.size(48.dp)
|
||||
) {
|
||||
Box(
|
||||
@ -782,14 +781,14 @@ private fun AiMagicButton(
|
||||
if (isLoading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
color = Purple,
|
||||
color = MaterialTheme.colorScheme.tertiary,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.AutoAwesome,
|
||||
contentDescription = "Magie IA",
|
||||
tint = if (enabled) Purple else TextMuted,
|
||||
tint = if (enabled) MaterialTheme.colorScheme.tertiary else MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(22.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ import com.shaarit.domain.model.TagFilter
|
||||
import com.shaarit.domain.model.ViewStyle
|
||||
import com.shaarit.ui.components.PremiumTextField
|
||||
import com.shaarit.ui.components.TagChip
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Typography
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.animation.*
|
||||
@ -82,12 +82,12 @@ fun AccordionSection(
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
Icon(
|
||||
imageVector = if (expanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
|
||||
contentDescription = if (expanded) "Réduire" else "Développer",
|
||||
tint = TextMuted,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
}
|
||||
@ -136,14 +136,14 @@ fun DrawerNavigationItem(
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -158,7 +158,7 @@ fun DrawerCollectionItem(
|
||||
) {
|
||||
Surface(
|
||||
onClick = onClick,
|
||||
color = if (isSelected) CyanPrimary.copy(alpha = 0.15f) else Color.Transparent,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.15f) else Color.Transparent,
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@ -178,7 +178,7 @@ fun DrawerCollectionItem(
|
||||
Text(
|
||||
text = name,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = if (isSelected) CyanPrimary else TextPrimary,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground,
|
||||
fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
@ -188,7 +188,7 @@ fun DrawerCollectionItem(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(8.dp)
|
||||
.background(CyanPrimary, shape = MaterialTheme.shapes.small)
|
||||
.background(MaterialTheme.colorScheme.primary, shape = MaterialTheme.shapes.small)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -203,7 +203,7 @@ fun DrawerSmartCollectionItem(
|
||||
) {
|
||||
Surface(
|
||||
onClick = onClick,
|
||||
color = if (isSelected) CyanPrimary.copy(alpha = 0.15f) else Color.Transparent,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.15f) else Color.Transparent,
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@ -218,14 +218,14 @@ fun DrawerSmartCollectionItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.AutoAwesome,
|
||||
contentDescription = null,
|
||||
tint = if (isSelected) CyanPrimary else TealSecondary,
|
||||
tint = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Text(
|
||||
text = name,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = if (isSelected) CyanPrimary else TextPrimary,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground,
|
||||
fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
@ -235,7 +235,7 @@ fun DrawerSmartCollectionItem(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(8.dp)
|
||||
.background(CyanPrimary, shape = MaterialTheme.shapes.small)
|
||||
.background(MaterialTheme.colorScheme.primary, shape = MaterialTheme.shapes.small)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -251,16 +251,16 @@ fun DrawerTagChip(
|
||||
Surface(
|
||||
onClick = onClick,
|
||||
shape = MaterialTheme.shapes.small,
|
||||
color = if (isSelected) CyanPrimary.copy(alpha = 0.25f) else CardBackgroundElevated,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.25f) else MaterialTheme.colorScheme.primaryContainer,
|
||||
border = if (isSelected) {
|
||||
androidx.compose.foundation.BorderStroke(1.dp, CyanPrimary.copy(alpha = 0.5f))
|
||||
androidx.compose.foundation.BorderStroke(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.5f))
|
||||
} else null,
|
||||
modifier = Modifier.padding(2.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "#$tag",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = if (isSelected) CyanLight else TextSecondary,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.tertiary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp)
|
||||
)
|
||||
}
|
||||
@ -328,8 +328,8 @@ fun FeedScreen(
|
||||
drawerContent = {
|
||||
ModalDrawerSheet(
|
||||
modifier = Modifier.width(320.dp),
|
||||
drawerContainerColor = DeepNavy,
|
||||
drawerContentColor = TextPrimary
|
||||
drawerContainerColor = MaterialTheme.colorScheme.background,
|
||||
drawerContentColor = MaterialTheme.colorScheme.onBackground
|
||||
) {
|
||||
// Header avec logo et titre (fixe, ne défile pas)
|
||||
Column(
|
||||
@ -338,8 +338,8 @@ fun FeedScreen(
|
||||
.background(
|
||||
brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
CardBackgroundElevated,
|
||||
DeepNavy
|
||||
MaterialTheme.colorScheme.primaryContainer,
|
||||
MaterialTheme.colorScheme.background
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -350,7 +350,7 @@ fun FeedScreen(
|
||||
modifier = Modifier
|
||||
.size(56.dp)
|
||||
.background(
|
||||
color = CyanPrimary.copy(alpha = 0.15f),
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.15f),
|
||||
shape = MaterialTheme.shapes.large
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
@ -358,7 +358,7 @@ fun FeedScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Bookmark,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(28.dp)
|
||||
)
|
||||
}
|
||||
@ -369,13 +369,13 @@ fun FeedScreen(
|
||||
text = "ShaarIt",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "Vos liens, organisés",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
@ -453,7 +453,7 @@ fun FeedScreen(
|
||||
}
|
||||
|
||||
Divider(
|
||||
color = TextMuted.copy(alpha = 0.2f),
|
||||
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f),
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
|
||||
@ -584,7 +584,7 @@ fun FeedScreen(
|
||||
}
|
||||
|
||||
Divider(
|
||||
color = TextMuted.copy(alpha = 0.2f),
|
||||
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f),
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
|
||||
@ -603,7 +603,7 @@ fun FeedScreen(
|
||||
Text(
|
||||
"Voir tout",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = CyanPrimary
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -650,7 +650,7 @@ fun FeedScreen(
|
||||
}
|
||||
|
||||
Divider(
|
||||
color = TextMuted.copy(alpha = 0.2f),
|
||||
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f),
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
|
||||
@ -669,7 +669,7 @@ fun FeedScreen(
|
||||
Text(
|
||||
"Voir tout",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = CyanPrimary
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -702,7 +702,7 @@ fun FeedScreen(
|
||||
Text(
|
||||
text = "© 2026 ShaarIt",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted.copy(alpha = 0.6f),
|
||||
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.6f),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
@ -716,7 +716,7 @@ fun FeedScreen(
|
||||
.fillMaxSize()
|
||||
.background(
|
||||
brush = Brush.verticalGradient(
|
||||
colors = listOf(DeepNavy, DarkNavy)
|
||||
colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface)
|
||||
)
|
||||
)
|
||||
) {
|
||||
@ -729,7 +729,7 @@ fun FeedScreen(
|
||||
"ShaarIt",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
@ -743,7 +743,7 @@ fun FeedScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = "Exit selection",
|
||||
tint = CyanPrimary
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@ -751,7 +751,7 @@ fun FeedScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Menu,
|
||||
contentDescription = "Menu",
|
||||
tint = CyanPrimary
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -760,7 +760,7 @@ fun FeedScreen(
|
||||
if (selectionMode) {
|
||||
Text(
|
||||
text = selectedIds.size.toString(),
|
||||
color = TextSecondary,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(horizontal = 8.dp)
|
||||
)
|
||||
IconButton(
|
||||
@ -770,7 +770,7 @@ fun FeedScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Folder,
|
||||
contentDescription = "Add to collection",
|
||||
tint = if (selectedIds.isNotEmpty()) CyanPrimary else TextMuted
|
||||
tint = if (selectedIds.isNotEmpty()) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
@ -782,7 +782,7 @@ fun FeedScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = "Cancel selection",
|
||||
tint = TextSecondary
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
return@TopAppBar
|
||||
@ -797,7 +797,7 @@ fun FeedScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Refresh,
|
||||
contentDescription = "Refresh",
|
||||
tint = CyanPrimary
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
|
||||
@ -811,14 +811,14 @@ fun FeedScreen(
|
||||
ViewStyle.COMPACT -> Icons.Default.ViewList
|
||||
},
|
||||
contentDescription = "View style",
|
||||
tint = CyanPrimary
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
|
||||
DropdownMenu(
|
||||
expanded = showViewStyleMenu,
|
||||
onDismissRequest = { showViewStyleMenu = false },
|
||||
modifier = Modifier.background(CardBackground)
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.surfaceVariant)
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
@ -829,11 +829,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.ViewStream,
|
||||
contentDescription = null,
|
||||
tint = if (viewStyle == ViewStyle.LIST) CyanPrimary else TextSecondary
|
||||
tint = if (viewStyle == ViewStyle.LIST) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"List View",
|
||||
color = if (viewStyle == ViewStyle.LIST) CyanPrimary else TextPrimary
|
||||
color = if (viewStyle == ViewStyle.LIST) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -851,11 +851,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.ViewModule,
|
||||
contentDescription = null,
|
||||
tint = if (viewStyle == ViewStyle.GRID) CyanPrimary else TextSecondary
|
||||
tint = if (viewStyle == ViewStyle.GRID) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Grid View",
|
||||
color = if (viewStyle == ViewStyle.GRID) CyanPrimary else TextPrimary
|
||||
color = if (viewStyle == ViewStyle.GRID) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -873,11 +873,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.ViewList,
|
||||
contentDescription = null,
|
||||
tint = if (viewStyle == ViewStyle.COMPACT) CyanPrimary else TextSecondary
|
||||
tint = if (viewStyle == ViewStyle.COMPACT) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Compact View",
|
||||
color = if (viewStyle == ViewStyle.COMPACT) CyanPrimary else TextPrimary
|
||||
color = if (viewStyle == ViewStyle.COMPACT) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -895,20 +895,20 @@ fun FeedScreen(
|
||||
Icon(
|
||||
imageVector = Icons.Default.FilterList,
|
||||
contentDescription = "Filters",
|
||||
tint = CyanPrimary
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
|
||||
DropdownMenu(
|
||||
expanded = showSortOrderMenu,
|
||||
onDismissRequest = { showSortOrderMenu = false },
|
||||
modifier = Modifier.background(CardBackground)
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.surfaceVariant)
|
||||
) {
|
||||
// Sort Direction Section
|
||||
Text(
|
||||
text = "TRI",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
DropdownMenuItem(
|
||||
@ -920,11 +920,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.ArrowDownward,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.sortDirection == SortDirection.NEWEST_FIRST) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.sortDirection == SortDirection.NEWEST_FIRST) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Plus récent d'abord",
|
||||
color = if (bookmarkFilter.sortDirection == SortDirection.NEWEST_FIRST) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.sortDirection == SortDirection.NEWEST_FIRST) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -941,11 +941,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.ArrowUpward,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.sortDirection == SortDirection.OLDEST_FIRST) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.sortDirection == SortDirection.OLDEST_FIRST) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Plus ancien d'abord",
|
||||
color = if (bookmarkFilter.sortDirection == SortDirection.OLDEST_FIRST) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.sortDirection == SortDirection.OLDEST_FIRST) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -954,13 +954,13 @@ fun FeedScreen(
|
||||
}
|
||||
)
|
||||
|
||||
Divider(color = TextMuted.copy(alpha = 0.2f))
|
||||
Divider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f))
|
||||
|
||||
// Time Filter Section
|
||||
Text(
|
||||
text = "PÉRIODE",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
DropdownMenuItem(
|
||||
@ -972,11 +972,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.AllInclusive,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.timeFilter == TimeFilter.ALL) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.timeFilter == TimeFilter.ALL) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Tous les bookmarks",
|
||||
color = if (bookmarkFilter.timeFilter == TimeFilter.ALL) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.timeFilter == TimeFilter.ALL) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -993,11 +993,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.Today,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.timeFilter == TimeFilter.TODAY) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.timeFilter == TimeFilter.TODAY) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Aujourd'hui",
|
||||
color = if (bookmarkFilter.timeFilter == TimeFilter.TODAY) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.timeFilter == TimeFilter.TODAY) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -1014,11 +1014,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.DateRange,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.timeFilter == TimeFilter.THIS_WEEK) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.timeFilter == TimeFilter.THIS_WEEK) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Cette semaine",
|
||||
color = if (bookmarkFilter.timeFilter == TimeFilter.THIS_WEEK) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.timeFilter == TimeFilter.THIS_WEEK) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -1035,11 +1035,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.CalendarMonth,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.timeFilter == TimeFilter.THIS_MONTH) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.timeFilter == TimeFilter.THIS_MONTH) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Ce mois-ci",
|
||||
color = if (bookmarkFilter.timeFilter == TimeFilter.THIS_MONTH) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.timeFilter == TimeFilter.THIS_MONTH) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -1048,13 +1048,13 @@ fun FeedScreen(
|
||||
}
|
||||
)
|
||||
|
||||
Divider(color = TextMuted.copy(alpha = 0.2f))
|
||||
Divider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f))
|
||||
|
||||
// Visibility Filter Section
|
||||
Text(
|
||||
text = "VISIBILITÉ",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
DropdownMenuItem(
|
||||
@ -1066,11 +1066,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.Visibility,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.visibilityFilter == VisibilityFilter.ALL) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.visibilityFilter == VisibilityFilter.ALL) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Publics et Privés",
|
||||
color = if (bookmarkFilter.visibilityFilter == VisibilityFilter.ALL) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.visibilityFilter == VisibilityFilter.ALL) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -1087,11 +1087,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.Public,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.visibilityFilter == VisibilityFilter.PUBLIC_ONLY) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.visibilityFilter == VisibilityFilter.PUBLIC_ONLY) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Publics uniquement",
|
||||
color = if (bookmarkFilter.visibilityFilter == VisibilityFilter.PUBLIC_ONLY) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.visibilityFilter == VisibilityFilter.PUBLIC_ONLY) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -1108,11 +1108,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.Lock,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.visibilityFilter == VisibilityFilter.PRIVATE_ONLY) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.visibilityFilter == VisibilityFilter.PRIVATE_ONLY) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Privés uniquement",
|
||||
color = if (bookmarkFilter.visibilityFilter == VisibilityFilter.PRIVATE_ONLY) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.visibilityFilter == VisibilityFilter.PRIVATE_ONLY) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -1121,13 +1121,13 @@ fun FeedScreen(
|
||||
}
|
||||
)
|
||||
|
||||
Divider(color = TextMuted.copy(alpha = 0.2f))
|
||||
Divider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f))
|
||||
|
||||
// Tag Filter Section
|
||||
Text(
|
||||
text = "TAGS",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
DropdownMenuItem(
|
||||
@ -1139,11 +1139,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.Label,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.tagFilter == TagFilter.ALL) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.tagFilter == TagFilter.ALL) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Tous les tags",
|
||||
color = if (bookmarkFilter.tagFilter == TagFilter.ALL) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.tagFilter == TagFilter.ALL) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -1160,11 +1160,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.LabelOff,
|
||||
contentDescription = null,
|
||||
tint = if (bookmarkFilter.tagFilter == TagFilter.UNTAGGED) CyanPrimary else TextSecondary
|
||||
tint = if (bookmarkFilter.tagFilter == TagFilter.UNTAGGED) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Sans tags",
|
||||
color = if (bookmarkFilter.tagFilter == TagFilter.UNTAGGED) CyanPrimary else TextPrimary
|
||||
color = if (bookmarkFilter.tagFilter == TagFilter.UNTAGGED) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -1173,7 +1173,7 @@ fun FeedScreen(
|
||||
}
|
||||
)
|
||||
|
||||
Divider(color = TextMuted.copy(alpha = 0.2f))
|
||||
Divider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f))
|
||||
|
||||
// Reset button
|
||||
DropdownMenuItem(
|
||||
@ -1185,11 +1185,11 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.Refresh,
|
||||
contentDescription = null,
|
||||
tint = TextSecondary
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"Réinitialiser les filtres",
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -1202,8 +1202,8 @@ fun FeedScreen(
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = DeepNavy.copy(alpha = 0.9f),
|
||||
titleContentColor = TextPrimary
|
||||
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
|
||||
titleContentColor = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
)
|
||||
|
||||
@ -1220,7 +1220,7 @@ fun FeedScreen(
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(DarkNavy)
|
||||
.background(MaterialTheme.colorScheme.surface)
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
verticalAlignment = Alignment.Top,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
@ -1228,7 +1228,7 @@ fun FeedScreen(
|
||||
Text(
|
||||
"Filtering by:",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(top = 6.dp)
|
||||
)
|
||||
|
||||
@ -1240,8 +1240,8 @@ fun FeedScreen(
|
||||
onClick = { viewModel.clearCollectionFilter() },
|
||||
label = { Text(collectionName) },
|
||||
colors = AssistChipDefaults.assistChipColors(
|
||||
containerColor = CardBackground,
|
||||
labelColor = CyanPrimary
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
labelColor = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -1282,7 +1282,7 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.Close,
|
||||
contentDescription = "Clear filter",
|
||||
tint = TextMuted,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -1300,7 +1300,7 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.Search,
|
||||
contentDescription = null,
|
||||
tint = TextMuted
|
||||
tint = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
},
|
||||
trailingIcon = {
|
||||
@ -1311,7 +1311,7 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.Close,
|
||||
contentDescription = "Clear",
|
||||
tint = TextMuted
|
||||
tint = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1324,8 +1324,8 @@ fun FeedScreen(
|
||||
floatingActionButton = {
|
||||
FloatingActionButton(
|
||||
onClick = onNavigateToAdd,
|
||||
containerColor = CyanPrimary,
|
||||
contentColor = DeepNavy
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
contentColor = MaterialTheme.colorScheme.background
|
||||
) { Icon(Icons.Default.Add, contentDescription = "Add Link") }
|
||||
},
|
||||
containerColor = Color.Transparent
|
||||
@ -1350,7 +1350,7 @@ fun FeedScreen(
|
||||
Text(
|
||||
"Failed to load links",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = ErrorRed
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
IconButton(onClick = {
|
||||
@ -1360,7 +1360,7 @@ fun FeedScreen(
|
||||
Icon(
|
||||
Icons.Default.Refresh,
|
||||
contentDescription = "Refresh",
|
||||
tint = CyanPrimary
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1377,7 +1377,7 @@ fun FeedScreen(
|
||||
"No links found"
|
||||
else "No links yet",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
@ -1385,7 +1385,7 @@ fun FeedScreen(
|
||||
"Try a different search"
|
||||
else "Add your first link!",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1447,7 +1447,7 @@ fun FeedScreen(
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
color = CyanPrimary
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1507,7 +1507,7 @@ fun FeedScreen(
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
color = CyanPrimary
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1568,7 +1568,7 @@ fun FeedScreen(
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
color = CyanPrimary
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1584,8 +1584,8 @@ fun FeedScreen(
|
||||
refreshing = pagingItems.loadState.refresh is LoadState.Loading,
|
||||
state = pullRefreshState,
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
backgroundColor = DarkNavy,
|
||||
contentColor = CyanPrimary
|
||||
backgroundColor = MaterialTheme.colorScheme.surface,
|
||||
contentColor = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ import com.shaarit.domain.model.HealthStatus
|
||||
import com.shaarit.domain.model.ShaarliLink
|
||||
import com.shaarit.ui.components.GlassCard
|
||||
import com.shaarit.ui.components.TagChip
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Typography
|
||||
import dev.jeziellago.compose.markdowntext.MarkdownText
|
||||
import coil.compose.AsyncImage
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
@ -78,7 +78,7 @@ fun ListViewItem(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = { (onItemClick ?: { onLinkClick(link.url) }).invoke() },
|
||||
onLongClick = onItemLongClick,
|
||||
glowColor = if (isSelected) CyanPrimary else CyanPrimary
|
||||
glowColor = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primary
|
||||
) {
|
||||
Column {
|
||||
Row(
|
||||
@ -103,7 +103,7 @@ fun ListViewItem(
|
||||
text = link.displayTitle,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = CyanPrimary,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
@ -118,9 +118,9 @@ fun ListViewItem(
|
||||
text = link.url,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = when (link.healthStatus) {
|
||||
HealthStatus.DEAD -> ErrorRed
|
||||
HealthStatus.OK -> TealSecondary
|
||||
else -> TextMuted
|
||||
HealthStatus.DEAD -> MaterialTheme.colorScheme.error
|
||||
HealthStatus.OK -> MaterialTheme.colorScheme.secondary
|
||||
else -> MaterialTheme.colorScheme.outline
|
||||
},
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
@ -143,7 +143,7 @@ fun ListViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.PushPin,
|
||||
contentDescription = if (link.isPinned) "Désépingler" else "Épingler",
|
||||
tint = if (link.isPinned) CyanPrimary else TextMuted,
|
||||
tint = if (link.isPinned) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -151,7 +151,7 @@ fun ListViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Visibility,
|
||||
contentDescription = "View Details",
|
||||
tint = CyanPrimary.copy(alpha = 0.7f),
|
||||
tint = MaterialTheme.colorScheme.primary.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -159,7 +159,7 @@ fun ListViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Edit,
|
||||
contentDescription = "Edit",
|
||||
tint = TealSecondary.copy(alpha = 0.7f),
|
||||
tint = MaterialTheme.colorScheme.secondary.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -167,7 +167,7 @@ fun ListViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Delete,
|
||||
contentDescription = "Delete",
|
||||
tint = ErrorRed.copy(alpha = 0.7f),
|
||||
tint = MaterialTheme.colorScheme.error.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
@ -178,7 +178,7 @@ fun ListViewItem(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
MarkdownText(
|
||||
markdown = link.description,
|
||||
style = MaterialTheme.typography.bodyMedium.copy(color = TextSecondary),
|
||||
style = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onSurfaceVariant),
|
||||
maxLines = 5,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@ -203,7 +203,7 @@ fun ListViewItem(
|
||||
Text(
|
||||
text = link.date,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
|
||||
if (link.isPrivate) {
|
||||
@ -214,13 +214,13 @@ fun ListViewItem(
|
||||
Icon(
|
||||
Icons.Default.Lock,
|
||||
contentDescription = "Private",
|
||||
tint = TextMuted,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(12.dp)
|
||||
)
|
||||
Text(
|
||||
text = "Private",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -264,7 +264,7 @@ fun GridViewItem(
|
||||
.heightIn(min = 220.dp),
|
||||
onClick = { (onItemClick ?: { onLinkClick(link.url) }).invoke() },
|
||||
onLongClick = onItemLongClick,
|
||||
glowColor = if (isSelected) CyanPrimary else CyanPrimary
|
||||
glowColor = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primary
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
@ -301,9 +301,9 @@ fun GridViewItem(
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = when (link.healthStatus) {
|
||||
HealthStatus.DEAD -> ErrorRed
|
||||
HealthStatus.OK -> CyanPrimary
|
||||
else -> CyanPrimary.copy(alpha = 0.7f)
|
||||
HealthStatus.DEAD -> MaterialTheme.colorScheme.error
|
||||
HealthStatus.OK -> MaterialTheme.colorScheme.primary
|
||||
else -> MaterialTheme.colorScheme.primary.copy(alpha = 0.7f)
|
||||
},
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
@ -314,7 +314,7 @@ fun GridViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.PushPin,
|
||||
contentDescription = "Épinglé",
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
}
|
||||
@ -326,7 +326,7 @@ fun GridViewItem(
|
||||
if (link.description.isNotBlank()) {
|
||||
MarkdownText(
|
||||
markdown = link.description,
|
||||
style = MaterialTheme.typography.bodySmall.copy(color = TextSecondary),
|
||||
style = MaterialTheme.typography.bodySmall.copy(color = MaterialTheme.colorScheme.onSurfaceVariant),
|
||||
maxLines = 3,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@ -344,7 +344,7 @@ fun GridViewItem(
|
||||
Text(
|
||||
text = "#$tag",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TealSecondary,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
@ -353,7 +353,7 @@ fun GridViewItem(
|
||||
Text(
|
||||
text = "+${link.tags.size - 2}",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -379,14 +379,14 @@ fun GridViewItem(
|
||||
Icon(
|
||||
Icons.Default.Lock,
|
||||
contentDescription = "Private",
|
||||
tint = TextMuted,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(12.dp)
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = link.date.take(10),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
|
||||
@ -399,7 +399,7 @@ fun GridViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.PushPin,
|
||||
contentDescription = if (link.isPinned) "Désépingler" else "Épingler",
|
||||
tint = if (link.isPinned) CyanPrimary else TextMuted,
|
||||
tint = if (link.isPinned) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
@ -410,7 +410,7 @@ fun GridViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Visibility,
|
||||
contentDescription = "View Details",
|
||||
tint = CyanPrimary.copy(alpha = 0.7f),
|
||||
tint = MaterialTheme.colorScheme.primary.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
@ -421,7 +421,7 @@ fun GridViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Edit,
|
||||
contentDescription = "Edit",
|
||||
tint = TealSecondary.copy(alpha = 0.7f),
|
||||
tint = MaterialTheme.colorScheme.secondary.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
@ -432,7 +432,7 @@ fun GridViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Delete,
|
||||
contentDescription = "Delete",
|
||||
tint = ErrorRed.copy(alpha = 0.7f),
|
||||
tint = MaterialTheme.colorScheme.error.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
@ -481,7 +481,7 @@ fun CompactViewItem(
|
||||
onClick = { (onItemClick ?: { onLinkClick(link.url) }).invoke() },
|
||||
onLongClick = onItemLongClick
|
||||
),
|
||||
color = CardBackground.copy(alpha = 0.7f)
|
||||
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.7f)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@ -506,7 +506,7 @@ fun CompactViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.PushPin,
|
||||
contentDescription = "Épinglé",
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
@ -515,7 +515,7 @@ fun CompactViewItem(
|
||||
Icon(
|
||||
Icons.Default.Lock,
|
||||
contentDescription = "Private",
|
||||
tint = TextMuted,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
@ -531,9 +531,9 @@ fun CompactViewItem(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Medium,
|
||||
color = when (link.healthStatus) {
|
||||
HealthStatus.DEAD -> ErrorRed
|
||||
HealthStatus.OK -> CyanPrimary
|
||||
else -> CyanPrimary.copy(alpha = 0.7f)
|
||||
HealthStatus.DEAD -> MaterialTheme.colorScheme.error
|
||||
HealthStatus.OK -> MaterialTheme.colorScheme.primary
|
||||
else -> MaterialTheme.colorScheme.primary.copy(alpha = 0.7f)
|
||||
},
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
@ -547,14 +547,14 @@ fun CompactViewItem(
|
||||
Text(
|
||||
text = link.date.take(10),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
|
||||
if (link.tags.isNotEmpty()) {
|
||||
Text(
|
||||
text = link.tags.take(2).joinToString { "#$it" },
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TealSecondary,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
@ -571,7 +571,7 @@ fun CompactViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.PushPin,
|
||||
contentDescription = if (link.isPinned) "Désépingler" else "Épingler",
|
||||
tint = if (link.isPinned) CyanPrimary else TextMuted,
|
||||
tint = if (link.isPinned) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
}
|
||||
@ -579,7 +579,7 @@ fun CompactViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Visibility,
|
||||
contentDescription = "View Details",
|
||||
tint = CyanPrimary.copy(alpha = 0.7f),
|
||||
tint = MaterialTheme.colorScheme.primary.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
}
|
||||
@ -587,7 +587,7 @@ fun CompactViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Edit,
|
||||
contentDescription = "Edit",
|
||||
tint = TealSecondary.copy(alpha = 0.7f),
|
||||
tint = MaterialTheme.colorScheme.secondary.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
}
|
||||
@ -595,7 +595,7 @@ fun CompactViewItem(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Delete,
|
||||
contentDescription = "Delete",
|
||||
tint = ErrorRed.copy(alpha = 0.7f),
|
||||
tint = MaterialTheme.colorScheme.error.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
}
|
||||
@ -615,14 +615,14 @@ fun DeleteConfirmationDialog(
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text("Delete Link", fontWeight = FontWeight.Bold, color = TextPrimary) },
|
||||
title = { Text("Delete Link", fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.onBackground) },
|
||||
text = {
|
||||
Column {
|
||||
Text("Are you sure you want to delete this link?", color = TextSecondary)
|
||||
Text("Are you sure you want to delete this link?", color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
linkTitle,
|
||||
color = CyanPrimary,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
fontWeight = FontWeight.Medium,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
@ -631,17 +631,17 @@ fun DeleteConfirmationDialog(
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = onConfirm) {
|
||||
Text("Delete", color = ErrorRed)
|
||||
Text("Delete", color = MaterialTheme.colorScheme.error)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text("Cancel", color = TextMuted)
|
||||
Text("Cancel", color = MaterialTheme.colorScheme.outline)
|
||||
}
|
||||
},
|
||||
containerColor = CardBackground,
|
||||
titleContentColor = TextPrimary,
|
||||
textContentColor = TextSecondary
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
titleContentColor = MaterialTheme.colorScheme.onBackground,
|
||||
textContentColor = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
@ -691,7 +691,7 @@ fun LinkDetailsView(
|
||||
text = link.displayTitle,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = CyanPrimary,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
IconButton(
|
||||
@ -703,7 +703,7 @@ fun LinkDetailsView(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = "Close",
|
||||
tint = TextSecondary
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -734,7 +734,7 @@ fun LinkDetailsView(
|
||||
Text(
|
||||
text = link.url,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TealSecondary,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
modifier = Modifier
|
||||
.clickable { onLinkClick(link.url) }
|
||||
.padding(vertical = 4.dp)
|
||||
@ -767,7 +767,7 @@ fun LinkDetailsView(
|
||||
Text(
|
||||
text = link.date,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
if (link.isPrivate) {
|
||||
Row(
|
||||
@ -777,34 +777,34 @@ fun LinkDetailsView(
|
||||
Icon(
|
||||
Icons.Default.Lock,
|
||||
contentDescription = "Private",
|
||||
tint = TextMuted,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
Text(
|
||||
text = "Private",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
Divider(color = TextMuted.copy(alpha = 0.2f))
|
||||
Divider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f))
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
// Description
|
||||
if (link.description.isNotBlank()) {
|
||||
MarkdownText(
|
||||
markdown = link.description,
|
||||
style = MaterialTheme.typography.bodyMedium.copy(color = TextPrimary),
|
||||
style = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onBackground),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = "No description",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
fontStyle = androidx.compose.ui.text.font.FontStyle.Italic
|
||||
)
|
||||
}
|
||||
@ -834,7 +834,7 @@ fun HealthStatusIcon(
|
||||
Icon(
|
||||
imageVector = Icons.Default.HelpOutline,
|
||||
contentDescription = "Non testé",
|
||||
tint = TextMuted,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
@ -842,7 +842,7 @@ fun HealthStatusIcon(
|
||||
Icon(
|
||||
imageVector = Icons.Default.CheckCircle,
|
||||
contentDescription = "Lien fonctionnel",
|
||||
tint = SuccessGreen,
|
||||
tint = Color(0xFF10B981),
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
@ -858,7 +858,7 @@ fun HealthStatusIcon(
|
||||
Icon(
|
||||
imageVector = Icons.Default.BrokenImage,
|
||||
contentDescription = "Lien mort",
|
||||
tint = ErrorRed,
|
||||
tint = MaterialTheme.colorScheme.error,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Typography
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@ -30,7 +30,7 @@ fun HelpScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(
|
||||
brush = Brush.verticalGradient(colors = listOf(DeepNavy, DarkNavy))
|
||||
brush = Brush.verticalGradient(colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface))
|
||||
)
|
||||
) {
|
||||
Scaffold(
|
||||
@ -48,13 +48,13 @@ fun HelpScreen(
|
||||
Icon(
|
||||
Icons.Default.ArrowBack,
|
||||
contentDescription = "Retour",
|
||||
tint = TextPrimary
|
||||
tint = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = DeepNavy.copy(alpha = 0.9f),
|
||||
titleContentColor = TextPrimary
|
||||
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
|
||||
titleContentColor = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
)
|
||||
},
|
||||
@ -600,7 +600,7 @@ fun HelpScreen(
|
||||
Text(
|
||||
text = "ShaarIt v1.0 • © 2026",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted.copy(alpha = 0.6f),
|
||||
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.6f),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@ -618,9 +618,9 @@ private fun HelpHeader() {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = CyanPrimary.copy(alpha = 0.15f)
|
||||
containerColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.15f)
|
||||
),
|
||||
border = androidx.compose.foundation.BorderStroke(1.dp, CyanPrimary.copy(alpha = 0.3f))
|
||||
border = androidx.compose.foundation.BorderStroke(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.3f))
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@ -632,7 +632,7 @@ private fun HelpHeader() {
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
.background(
|
||||
color = CyanPrimary.copy(alpha = 0.2f),
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.2f),
|
||||
shape = MaterialTheme.shapes.medium
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
@ -640,7 +640,7 @@ private fun HelpHeader() {
|
||||
Icon(
|
||||
imageVector = Icons.Default.MenuBook,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(28.dp)
|
||||
)
|
||||
}
|
||||
@ -650,12 +650,12 @@ private fun HelpHeader() {
|
||||
text = "Guide Complet",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
Text(
|
||||
text = "Tout ce qu'il faut savoir pour maîtriser ShaarIt",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -673,7 +673,7 @@ private fun HelpSection(
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = CardBackground
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant
|
||||
)
|
||||
) {
|
||||
Column {
|
||||
@ -691,7 +691,7 @@ private fun HelpSection(
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = CyanPrimary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
@ -699,13 +699,13 @@ private fun HelpSection(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = TextPrimary,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Icon(
|
||||
imageVector = if (isExpanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
|
||||
contentDescription = if (isExpanded) "Réduire" else "Développer",
|
||||
tint = TextMuted
|
||||
tint = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -720,7 +720,7 @@ private fun HelpSection(
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
) {
|
||||
Divider(color = TextMuted.copy(alpha = 0.2f))
|
||||
Divider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f))
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
content()
|
||||
}
|
||||
@ -744,7 +744,7 @@ private fun HelpSubsection(
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = TealSecondary,
|
||||
tint = MaterialTheme.colorScheme.secondary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
@ -753,13 +753,13 @@ private fun HelpSubsection(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
fontWeight = FontWeight.Medium,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
Text(
|
||||
text = description,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -770,7 +770,7 @@ private fun HelpText(text: String) {
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
@ -780,7 +780,7 @@ private fun HelpSubtitle(text: String) {
|
||||
text = text,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = CyanLight
|
||||
color = MaterialTheme.colorScheme.tertiary
|
||||
)
|
||||
}
|
||||
|
||||
@ -792,14 +792,14 @@ private fun HelpFeatureList(items: List<String>) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.CheckCircle,
|
||||
contentDescription = null,
|
||||
tint = SuccessGreen,
|
||||
tint = Color(0xFF10B981),
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = item,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -814,13 +814,13 @@ private fun HelpBulletList(items: List<String>) {
|
||||
Text(
|
||||
text = "•",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = CyanPrimary,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.width(16.dp)
|
||||
)
|
||||
Text(
|
||||
text = item,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -836,7 +836,7 @@ private fun HelpNumberedList(items: List<Pair<String, String>>) {
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.background(
|
||||
color = CyanPrimary.copy(alpha = 0.2f),
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.2f),
|
||||
shape = MaterialTheme.shapes.small
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
@ -845,7 +845,7 @@ private fun HelpNumberedList(items: List<Pair<String, String>>) {
|
||||
text = "${index + 1}",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = CyanPrimary
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
@ -854,14 +854,14 @@ private fun HelpNumberedList(items: List<Pair<String, String>>) {
|
||||
text = title,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Medium,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
if (description.isNotBlank()) {
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
Text(
|
||||
text = description,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -878,7 +878,7 @@ private fun HelpInfoCard(
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = CardBackgroundElevated
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer
|
||||
)
|
||||
) {
|
||||
Column(
|
||||
@ -888,7 +888,7 @@ private fun HelpInfoCard(
|
||||
Icon(
|
||||
imageVector = Icons.Default.Info,
|
||||
contentDescription = null,
|
||||
tint = TealSecondary,
|
||||
tint = MaterialTheme.colorScheme.secondary,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
@ -896,14 +896,14 @@ private fun HelpInfoCard(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = TealSecondary
|
||||
color = MaterialTheme.colorScheme.secondary
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
text = content,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -915,7 +915,7 @@ private fun HelpTip(text: String) {
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(
|
||||
color = SuccessGreen.copy(alpha = 0.1f),
|
||||
color = Color(0xFF10B981).copy(alpha = 0.1f),
|
||||
shape = MaterialTheme.shapes.small
|
||||
)
|
||||
.padding(12.dp),
|
||||
@ -924,14 +924,14 @@ private fun HelpTip(text: String) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Lightbulb,
|
||||
contentDescription = null,
|
||||
tint = SuccessGreen,
|
||||
tint = Color(0xFF10B981),
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,10 +5,16 @@ import android.net.Uri
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
@ -18,14 +24,19 @@ import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.shaarit.data.export.BookmarkImporter
|
||||
import com.shaarit.ui.theme.AppTheme
|
||||
import com.shaarit.ui.theme.ThemePreferences
|
||||
import com.shaarit.ui.theme.getColorSchemeForTheme
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
@ -34,10 +45,12 @@ import java.util.*
|
||||
fun SettingsScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateToDashboard: () -> Unit,
|
||||
viewModel: SettingsViewModel = hiltViewModel()
|
||||
viewModel: SettingsViewModel = hiltViewModel(),
|
||||
themePreferences: ThemePreferences = viewModel.themePreferences
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val uiState by viewModel.uiState.collectAsState()
|
||||
val currentTheme by themePreferences.currentTheme.collectAsState()
|
||||
|
||||
// Export JSON
|
||||
val exportJsonLauncher = rememberLauncherForActivityResult(
|
||||
@ -101,8 +114,21 @@ fun SettingsScreen(
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
// Theme Section
|
||||
item {
|
||||
SettingsSection(title = "Apparence")
|
||||
}
|
||||
|
||||
item {
|
||||
ThemePickerItem(
|
||||
currentTheme = currentTheme,
|
||||
onThemeSelected = { themePreferences.setTheme(it) }
|
||||
)
|
||||
}
|
||||
|
||||
// AI Section - Gemini API Key
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
SettingsSection(title = "Intelligence Artificielle")
|
||||
}
|
||||
|
||||
@ -668,3 +694,153 @@ private fun HealthCheckStatusItem(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ThemePickerItem(
|
||||
currentTheme: AppTheme,
|
||||
onThemeSelected: (AppTheme) -> Unit
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Palette,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Column {
|
||||
Text(
|
||||
text = "Th\u00e8me",
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
Text(
|
||||
text = currentTheme.displayName,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
LazyRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
items(AppTheme.entries.toList()) { theme ->
|
||||
ThemePreviewCard(
|
||||
theme = theme,
|
||||
isSelected = theme == currentTheme,
|
||||
onClick = { onThemeSelected(theme) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ThemePreviewCard(
|
||||
theme: AppTheme,
|
||||
isSelected: Boolean,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
val colors = getColorSchemeForTheme(theme)
|
||||
val borderColor = if (isSelected) MaterialTheme.colorScheme.primary else colors.outline
|
||||
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.width(100.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.clickable(onClick = onClick)
|
||||
) {
|
||||
// Mini preview card
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(72.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.border(
|
||||
BorderStroke(
|
||||
if (isSelected) 2.dp else 1.dp,
|
||||
borderColor
|
||||
),
|
||||
RoundedCornerShape(12.dp)
|
||||
)
|
||||
.background(colors.background)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(8.dp),
|
||||
verticalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
// Simulated top bar
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(6.dp)
|
||||
.clip(RoundedCornerShape(3.dp))
|
||||
.background(colors.surface)
|
||||
)
|
||||
// Simulated content lines
|
||||
Column(verticalArrangement = Arrangement.spacedBy(3.dp)) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.7f)
|
||||
.height(4.dp)
|
||||
.clip(RoundedCornerShape(2.dp))
|
||||
.background(colors.onBackground.copy(alpha = 0.6f))
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.5f)
|
||||
.height(4.dp)
|
||||
.clip(RoundedCornerShape(2.dp))
|
||||
.background(colors.onSurfaceVariant.copy(alpha = 0.4f))
|
||||
)
|
||||
}
|
||||
// Simulated accent button
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(24.dp)
|
||||
.height(6.dp)
|
||||
.clip(RoundedCornerShape(3.dp))
|
||||
.background(colors.primary)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
|
||||
// Theme name
|
||||
Text(
|
||||
text = theme.displayName,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
|
||||
// Description
|
||||
Text(
|
||||
text = theme.description,
|
||||
style = MaterialTheme.typography.labelSmall.copy(
|
||||
fontSize = androidx.compose.ui.unit.TextUnit(9f, androidx.compose.ui.unit.TextUnitType.Sp)
|
||||
),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f),
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import com.shaarit.data.sync.SyncManager
|
||||
import com.shaarit.data.sync.SyncState
|
||||
import com.shaarit.data.worker.LinkHealthCheckWorker
|
||||
import com.shaarit.domain.usecase.ClassifyBookmarksUseCase
|
||||
import com.shaarit.ui.theme.ThemePreferences
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
@ -29,7 +30,8 @@ class SettingsViewModel @Inject constructor(
|
||||
private val linkDao: LinkDao,
|
||||
private val classifyBookmarksUseCase: ClassifyBookmarksUseCase,
|
||||
private val tokenManager: TokenManager,
|
||||
private val workManager: WorkManager
|
||||
private val workManager: WorkManager,
|
||||
val themePreferences: ThemePreferences
|
||||
) : ViewModel() {
|
||||
|
||||
private val _uiState = MutableStateFlow(SettingsUiState())
|
||||
|
||||
@ -30,7 +30,7 @@ import com.shaarit.domain.model.ShaarliTag
|
||||
import com.shaarit.ui.components.GlassCard
|
||||
import com.shaarit.ui.components.PremiumTextField
|
||||
import com.shaarit.ui.components.TagChip
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Typography
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@ -48,7 +48,7 @@ fun TagsScreen(
|
||||
.background(
|
||||
brush =
|
||||
Brush.verticalGradient(
|
||||
colors = listOf(DeepNavy, DarkNavy)
|
||||
colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface)
|
||||
)
|
||||
)
|
||||
) {
|
||||
@ -67,14 +67,14 @@ fun TagsScreen(
|
||||
Icon(
|
||||
Icons.Default.ArrowBack,
|
||||
contentDescription = "Back",
|
||||
tint = TextPrimary
|
||||
tint = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
}
|
||||
},
|
||||
colors =
|
||||
TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = DeepNavy.copy(alpha = 0.9f),
|
||||
titleContentColor = TextPrimary
|
||||
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
|
||||
titleContentColor = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
)
|
||||
|
||||
@ -85,7 +85,7 @@ fun TagsScreen(
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
placeholder = "Search tags...",
|
||||
leadingIcon = {
|
||||
Icon(Icons.Default.Search, contentDescription = null, tint = TextMuted)
|
||||
Icon(Icons.Default.Search, contentDescription = null, tint = MaterialTheme.colorScheme.outline)
|
||||
},
|
||||
trailingIcon = {
|
||||
if (searchQuery.isNotEmpty()) {
|
||||
@ -93,7 +93,7 @@ fun TagsScreen(
|
||||
Icon(
|
||||
Icons.Default.Close,
|
||||
contentDescription = "Clear",
|
||||
tint = TextMuted
|
||||
tint = MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -103,7 +103,7 @@ fun TagsScreen(
|
||||
when (val state = uiState) {
|
||||
is TagsUiState.Loading -> {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator(color = CyanPrimary)
|
||||
CircularProgressIndicator(color = MaterialTheme.colorScheme.primary)
|
||||
}
|
||||
}
|
||||
is TagsUiState.Error -> {
|
||||
@ -112,13 +112,13 @@ fun TagsScreen(
|
||||
Text(
|
||||
"Failed to load tags",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = ErrorRed
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
state.message,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -139,7 +139,7 @@ fun TagsScreen(
|
||||
private fun TagsGridView(tags: List<ShaarliTag>, onTagClick: (ShaarliTag) -> Unit) {
|
||||
if (tags.isEmpty()) {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
Text("No tags found", style = MaterialTheme.typography.bodyLarge, color = TextSecondary)
|
||||
Text("No tags found", style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
}
|
||||
} else {
|
||||
LazyVerticalGrid(
|
||||
@ -153,13 +153,13 @@ private fun TagsGridView(tags: List<ShaarliTag>, onTagClick: (ShaarliTag) -> Uni
|
||||
|
||||
@Composable
|
||||
private fun TagGridItem(tag: ShaarliTag, onClick: () -> Unit) {
|
||||
GlassCard(modifier = Modifier.fillMaxWidth(), onClick = onClick, glowColor = TealSecondary) {
|
||||
GlassCard(modifier = Modifier.fillMaxWidth(), onClick = onClick, glowColor = MaterialTheme.colorScheme.secondary) {
|
||||
Column(modifier = Modifier.padding(4.dp)) {
|
||||
Text(
|
||||
text = "#${tag.name}",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = CyanPrimary,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
@ -167,7 +167,7 @@ private fun TagGridItem(tag: ShaarliTag, onClick: () -> Unit) {
|
||||
Text(
|
||||
text = "${tag.occurrences} links",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.zIndex
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Typography
|
||||
import dev.jeziellago.compose.markdowntext.MarkdownText
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
@ -210,10 +210,10 @@ fun SimpleMarkdownEditor(
|
||||
// Zone d'édition principale (sans la toolbar - elle sera flottante)
|
||||
Box(
|
||||
modifier = modifier
|
||||
.background(CardBackgroundElevated, RoundedCornerShape(12.dp))
|
||||
.background(MaterialTheme.colorScheme.primaryContainer, RoundedCornerShape(12.dp))
|
||||
.border(
|
||||
width = if (internalState.isFocused) 2.dp else 1.dp,
|
||||
color = if (internalState.isFocused) CyanPrimary else CyanPrimary.copy(alpha = 0.2f),
|
||||
color = if (internalState.isFocused) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primary.copy(alpha = 0.2f),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
)
|
||||
.padding(16.dp)
|
||||
@ -240,11 +240,11 @@ fun SimpleMarkdownEditor(
|
||||
.focusRequester(focusRequester)
|
||||
.onFocusChanged { internalState.isFocused = it.isFocused },
|
||||
textStyle = TextStyle(
|
||||
color = TextPrimary,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
fontSize = if (isNoteMode) 17.sp else 15.sp,
|
||||
lineHeight = if (isNoteMode) 26.sp else 22.sp
|
||||
),
|
||||
cursorBrush = SolidColor(CyanPrimary),
|
||||
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
|
||||
readOnly = readOnly,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
capitalization = KeyboardCapitalization.Sentences,
|
||||
@ -254,7 +254,7 @@ fun SimpleMarkdownEditor(
|
||||
if (internalState.textFieldValue.text.isEmpty()) {
|
||||
Text(
|
||||
text = placeholder,
|
||||
color = TextSecondary.copy(alpha = 0.6f),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
|
||||
fontSize = if (isNoteMode) 17.sp else 15.sp
|
||||
)
|
||||
}
|
||||
@ -366,7 +366,7 @@ fun FloatingMarkdownToolbar(
|
||||
modifier = modifier.padding(bottom = bottomPadding)
|
||||
) {
|
||||
Surface(
|
||||
color = CardBackground,
|
||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
||||
shadowElevation = 16.dp,
|
||||
tonalElevation = 8.dp,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
@ -417,7 +417,7 @@ fun MarkorStyleToolbar(
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Surface(
|
||||
color = CardBackground.copy(alpha = 0.95f),
|
||||
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.95f),
|
||||
shadowElevation = 8.dp,
|
||||
modifier = modifier.fillMaxWidth()
|
||||
) {
|
||||
@ -449,7 +449,7 @@ private fun MarkorToolButton(
|
||||
Surface(
|
||||
onClick = onClick,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
color = CardBackgroundElevated,
|
||||
color = MaterialTheme.colorScheme.primaryContainer,
|
||||
modifier = Modifier.size(42.dp)
|
||||
) {
|
||||
Box(
|
||||
@ -459,7 +459,7 @@ private fun MarkorToolButton(
|
||||
Icon(
|
||||
imageVector = tool.icon,
|
||||
contentDescription = tool.label,
|
||||
tint = TextSecondary,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.size(22.dp)
|
||||
)
|
||||
}
|
||||
@ -644,21 +644,21 @@ fun MarkdownPreview(
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.background(CardBackgroundElevated, RoundedCornerShape(12.dp))
|
||||
.border(1.dp, CyanPrimary.copy(alpha = 0.2f), RoundedCornerShape(12.dp))
|
||||
.background(MaterialTheme.colorScheme.primaryContainer, RoundedCornerShape(12.dp))
|
||||
.border(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.2f), RoundedCornerShape(12.dp))
|
||||
.padding(16.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
if (markdown.isBlank()) {
|
||||
Text(
|
||||
text = "Aucun contenu à prévisualiser...",
|
||||
color = TextSecondary.copy(alpha = 0.6f),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
} else {
|
||||
MarkdownText(
|
||||
markdown = markdown,
|
||||
color = TextPrimary,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
@ -786,8 +786,8 @@ private fun ModeToggleButton(
|
||||
Surface(
|
||||
onClick = onClick,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
color = if (isSelected) CyanPrimary.copy(alpha = 0.15f) else CardBackground,
|
||||
border = if (isSelected) androidx.compose.foundation.BorderStroke(1.dp, CyanPrimary) else null,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.15f) else MaterialTheme.colorScheme.surfaceVariant,
|
||||
border = if (isSelected) androidx.compose.foundation.BorderStroke(1.dp, MaterialTheme.colorScheme.primary) else null,
|
||||
modifier = modifier
|
||||
) {
|
||||
Row(
|
||||
@ -798,13 +798,13 @@ private fun ModeToggleButton(
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = if (isSelected) CyanPrimary else TextSecondary,
|
||||
tint = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(6.dp))
|
||||
Text(
|
||||
text = label,
|
||||
color = if (isSelected) CyanPrimary else TextSecondary,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
fontWeight = if (isSelected) FontWeight.Medium else FontWeight.Normal
|
||||
)
|
||||
@ -820,13 +820,13 @@ fun MarkdownHelp(modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.background(CardBackground.copy(alpha = 0.5f), RoundedCornerShape(8.dp))
|
||||
.background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f), RoundedCornerShape(8.dp))
|
||||
.padding(12.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Formatage rapide :",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextMuted,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
@ -850,13 +850,13 @@ fun MarkdownHelp(modifier: Modifier = Modifier) {
|
||||
@Composable
|
||||
private fun HelpChip(text: String) {
|
||||
Surface(
|
||||
color = CardBackgroundElevated,
|
||||
color = MaterialTheme.colorScheme.primaryContainer,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = TextSecondary,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
|
||||
fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace
|
||||
)
|
||||
|
||||
@ -24,7 +24,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.shaarit.ui.theme.*
|
||||
import com.shaarit.ui.theme.Typography
|
||||
|
||||
/** A glassmorphism-styled card with subtle border glow effect */
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@ -33,7 +33,7 @@ fun GlassCard(
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: (() -> Unit)? = null,
|
||||
onLongClick: (() -> Unit)? = null,
|
||||
glowColor: Color = CyanPrimary,
|
||||
glowColor: Color = MaterialTheme.colorScheme.primary,
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
) {
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
@ -77,8 +77,8 @@ fun GlassCard(
|
||||
Brush.verticalGradient(
|
||||
colors =
|
||||
listOf(
|
||||
CardBackground.copy(alpha = 0.95f),
|
||||
CardBackgroundElevated.copy(
|
||||
MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.95f),
|
||||
MaterialTheme.colorScheme.primaryContainer.copy(
|
||||
alpha = 0.9f
|
||||
)
|
||||
)
|
||||
@ -134,9 +134,9 @@ fun GradientButton(
|
||||
Brush.horizontalGradient(
|
||||
colors =
|
||||
if (enabled) {
|
||||
listOf(TealSecondary, CyanPrimary)
|
||||
listOf(MaterialTheme.colorScheme.secondary, MaterialTheme.colorScheme.primary)
|
||||
} else {
|
||||
listOf(TextMuted, TextMuted)
|
||||
listOf(MaterialTheme.colorScheme.outline, MaterialTheme.colorScheme.outline)
|
||||
}
|
||||
)
|
||||
|
||||
@ -150,8 +150,8 @@ fun GradientButton(
|
||||
.shadow(
|
||||
elevation = if (isPressed) 4.dp else 12.dp,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
ambientColor = CyanPrimary.copy(alpha = 0.3f),
|
||||
spotColor = CyanPrimary.copy(alpha = 0.4f)
|
||||
ambientColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f),
|
||||
spotColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.4f)
|
||||
)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(gradient)
|
||||
@ -176,7 +176,7 @@ fun GradientButton(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = DeepNavy
|
||||
color = MaterialTheme.colorScheme.background
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -194,19 +194,19 @@ fun TagChip(
|
||||
val backgroundColor by
|
||||
animateColorAsState(
|
||||
targetValue =
|
||||
if (isSelected) CyanPrimary.copy(alpha = 0.2f) else CardBackground,
|
||||
if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.2f) else MaterialTheme.colorScheme.surfaceVariant,
|
||||
animationSpec = tween(200)
|
||||
)
|
||||
|
||||
val borderColor by
|
||||
animateColorAsState(
|
||||
targetValue = if (isSelected) CyanPrimary else TextMuted.copy(alpha = 0.3f),
|
||||
targetValue = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline.copy(alpha = 0.3f),
|
||||
animationSpec = tween(200)
|
||||
)
|
||||
|
||||
val textColor by
|
||||
animateColorAsState(
|
||||
targetValue = if (isSelected) CyanPrimary else TextSecondary,
|
||||
targetValue = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
animationSpec = tween(200)
|
||||
)
|
||||
|
||||
@ -258,7 +258,7 @@ fun PremiumTextField(
|
||||
onValueChange = onValueChange,
|
||||
modifier = modifier,
|
||||
label = label?.let { { Text(it) } },
|
||||
placeholder = placeholder?.let { { Text(it, color = TextMuted) } },
|
||||
placeholder = placeholder?.let { { Text(it, color = MaterialTheme.colorScheme.outline) } },
|
||||
singleLine = singleLine,
|
||||
minLines = minLines,
|
||||
leadingIcon = leadingIcon,
|
||||
@ -278,15 +278,15 @@ fun PremiumTextField(
|
||||
},
|
||||
colors =
|
||||
OutlinedTextFieldDefaults.colors(
|
||||
focusedBorderColor = CyanPrimary,
|
||||
unfocusedBorderColor = SurfaceVariant,
|
||||
focusedLabelColor = CyanPrimary,
|
||||
unfocusedLabelColor = TextSecondary,
|
||||
cursorColor = CyanPrimary,
|
||||
focusedContainerColor = CardBackground.copy(alpha = 0.5f),
|
||||
unfocusedContainerColor = CardBackground.copy(alpha = 0.3f),
|
||||
errorBorderColor = ErrorRed,
|
||||
errorLabelColor = ErrorRed
|
||||
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
||||
unfocusedBorderColor = MaterialTheme.colorScheme.outlineVariant,
|
||||
focusedLabelColor = MaterialTheme.colorScheme.primary,
|
||||
unfocusedLabelColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
cursorColor = MaterialTheme.colorScheme.primary,
|
||||
focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f),
|
||||
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f),
|
||||
errorBorderColor = MaterialTheme.colorScheme.error,
|
||||
errorLabelColor = MaterialTheme.colorScheme.error
|
||||
),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
)
|
||||
@ -310,13 +310,13 @@ fun SectionHeader(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = TextPrimary
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
if (subtitle != null) {
|
||||
Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = TextSecondary
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -16,8 +17,6 @@ import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.shaarit.ui.theme.CardBackground
|
||||
import com.shaarit.ui.theme.CardBackgroundElevated
|
||||
|
||||
fun Modifier.shimmerEffect(): Modifier = composed {
|
||||
val transition = rememberInfiniteTransition(label = "shimmer")
|
||||
@ -53,7 +52,7 @@ fun SkeletonLinkCard(
|
||||
.fillMaxWidth()
|
||||
.height(200.dp)
|
||||
.clip(RoundedCornerShape(16.dp)), // Match GlassCard shape
|
||||
color = CardBackground.copy(alpha = 0.5f)
|
||||
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
||||
62
app/src/main/java/com/shaarit/ui/theme/AppTheme.kt
Normal file
62
app/src/main/java/com/shaarit/ui/theme/AppTheme.kt
Normal file
@ -0,0 +1,62 @@
|
||||
package com.shaarit.ui.theme
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
enum class AppTheme(
|
||||
val displayName: String,
|
||||
val description: String
|
||||
) {
|
||||
DEFAULT("ShaarIt", "Le thème original de l'application"),
|
||||
GITHUB("GitHub", "Mode sombre équilibré, contrastes doux"),
|
||||
LINEAR("Linear", "Dégradés subtils, teintes sombres douces"),
|
||||
SPOTIFY("Spotify", "Noir pur avec accents verts"),
|
||||
NOTION("Notion", "Sombre épuré, optimisé pour la lecture"),
|
||||
DISCORD("Discord", "Gris bleuté, référence des interfaces communautaires"),
|
||||
DRACULA("Dracula", "Sombre emblématique, accents rose, violet et vert"),
|
||||
ONE_DARK_PRO("One Dark Pro", "Inspiré d'Atom, contraste doux bleuté"),
|
||||
TOKYO_NIGHT("Tokyo Night", "Néons de Tokyo, bleu profond et couleurs électriques"),
|
||||
NORD("Nord", "Style arctique, bleus froids et gris clairs sereins"),
|
||||
NIGHT_OWL("Night Owl", "Optimisé pour la nuit, accessibilité renforcée"),
|
||||
ANTHRACITE("Anthracite", "Gris mat Material Design, réduit la fatigue oculaire"),
|
||||
CYBERPUNK("Cyberpunk", "Néons futuristes, cyan et magenta vibrants"),
|
||||
NAVY_ELEGANCE("Navy Élégance", "Bleu marine profond, touches dorées luxueuses"),
|
||||
EARTHY("Tons Terreux", "Verts forêt et bruns chocolat, ambiance organique");
|
||||
|
||||
companion object {
|
||||
fun fromName(name: String): AppTheme {
|
||||
return entries.find { it.name == name } ?: DEFAULT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
class ThemePreferences @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
) {
|
||||
private val prefs: SharedPreferences =
|
||||
context.getSharedPreferences("theme_prefs", Context.MODE_PRIVATE)
|
||||
|
||||
private val _currentTheme = MutableStateFlow(loadTheme())
|
||||
val currentTheme: StateFlow<AppTheme> = _currentTheme.asStateFlow()
|
||||
|
||||
private fun loadTheme(): AppTheme {
|
||||
val name = prefs.getString(KEY_THEME, AppTheme.DEFAULT.name) ?: AppTheme.DEFAULT.name
|
||||
return AppTheme.fromName(name)
|
||||
}
|
||||
|
||||
fun setTheme(theme: AppTheme) {
|
||||
prefs.edit().putString(KEY_THEME, theme.name).apply()
|
||||
_currentTheme.value = theme
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY_THEME = "selected_theme"
|
||||
}
|
||||
}
|
||||
@ -1,18 +1,12 @@
|
||||
package com.shaarit.ui.theme
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.core.view.WindowCompat
|
||||
|
||||
@ -47,7 +41,8 @@ val GradientEnd = Color(0xFF00D4AA)
|
||||
val Purple = Color(0xFFA855F7)
|
||||
val PurpleLight = Color(0xFFC084FC)
|
||||
|
||||
private val DarkColorScheme =
|
||||
// ── Default Theme (ShaarIt) ──
|
||||
private val DefaultDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = CyanPrimary,
|
||||
onPrimary = DeepNavy,
|
||||
@ -73,64 +68,414 @@ private val DarkColorScheme =
|
||||
onErrorContainer = Color(0xFFFCA5A5)
|
||||
)
|
||||
|
||||
private val LightColorScheme =
|
||||
lightColorScheme(
|
||||
primary = Color(0xFF0891B2),
|
||||
onPrimary = Color.White,
|
||||
primaryContainer = Color(0xFFCFFAFE),
|
||||
onPrimaryContainer = Color(0xFF164E63),
|
||||
secondary = Color(0xFF0284C7),
|
||||
onSecondary = Color.White,
|
||||
background = Color(0xFFF8FAFC),
|
||||
onBackground = Color(0xFF0F172A),
|
||||
surface = Color.White,
|
||||
onSurface = Color(0xFF0F172A),
|
||||
surfaceVariant = Color(0xFFF1F5F9),
|
||||
onSurfaceVariant = Color(0xFF475569)
|
||||
// ── GitHub (Smooth Dark) ──
|
||||
private val GitHubDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF58A6FF),
|
||||
onPrimary = Color(0xFF0D1117),
|
||||
primaryContainer = Color(0xFF1F2937),
|
||||
onPrimaryContainer = Color(0xFF79C0FF),
|
||||
secondary = Color(0xFF3FB950),
|
||||
onSecondary = Color(0xFF0D1117),
|
||||
secondaryContainer = Color(0xFF1C2D22),
|
||||
onSecondaryContainer = Color(0xFF56D364),
|
||||
tertiary = Color(0xFFD2A8FF),
|
||||
onTertiary = Color(0xFF0D1117),
|
||||
background = Color(0xFF0D1117),
|
||||
onBackground = Color(0xFFC9D1D9),
|
||||
surface = Color(0xFF161B22),
|
||||
onSurface = Color(0xFFC9D1D9),
|
||||
surfaceVariant = Color(0xFF21262D),
|
||||
onSurfaceVariant = Color(0xFF8B949E),
|
||||
outline = Color(0xFF30363D),
|
||||
outlineVariant = Color(0xFF21262D),
|
||||
error = Color(0xFFF85149),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF490202),
|
||||
onErrorContainer = Color(0xFFFFA198)
|
||||
)
|
||||
|
||||
// ── Linear (Soft Dark) ──
|
||||
private val LinearDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF5E6AD2),
|
||||
onPrimary = Color.White,
|
||||
primaryContainer = Color(0xFF2A2B3D),
|
||||
onPrimaryContainer = Color(0xFF8B8FE8),
|
||||
secondary = Color(0xFF4EA7FC),
|
||||
onSecondary = Color(0xFF12131A),
|
||||
secondaryContainer = Color(0xFF1E2A3A),
|
||||
onSecondaryContainer = Color(0xFF7DC4FF),
|
||||
tertiary = Color(0xFFE8A861),
|
||||
onTertiary = Color(0xFF12131A),
|
||||
background = Color(0xFF12131A),
|
||||
onBackground = Color(0xFFEEEFF2),
|
||||
surface = Color(0xFF1B1C24),
|
||||
onSurface = Color(0xFFEEEFF2),
|
||||
surfaceVariant = Color(0xFF22232E),
|
||||
onSurfaceVariant = Color(0xFF8A8F98),
|
||||
outline = Color(0xFF3B3D4A),
|
||||
outlineVariant = Color(0xFF2A2B3D),
|
||||
error = Color(0xFFEB5757),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF3D1515),
|
||||
onErrorContainer = Color(0xFFFF9B9B)
|
||||
)
|
||||
|
||||
// ── Spotify (Jet Black) ──
|
||||
private val SpotifyDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF1DB954),
|
||||
onPrimary = Color.Black,
|
||||
primaryContainer = Color(0xFF1A3D27),
|
||||
onPrimaryContainer = Color(0xFF1ED760),
|
||||
secondary = Color(0xFF1DB954),
|
||||
onSecondary = Color.Black,
|
||||
secondaryContainer = Color(0xFF1A3D27),
|
||||
onSecondaryContainer = Color(0xFF1ED760),
|
||||
tertiary = Color(0xFFB3B3B3),
|
||||
onTertiary = Color.Black,
|
||||
background = Color(0xFF000000),
|
||||
onBackground = Color(0xFFFFFFFF),
|
||||
surface = Color(0xFF121212),
|
||||
onSurface = Color(0xFFFFFFFF),
|
||||
surfaceVariant = Color(0xFF1A1A1A),
|
||||
onSurfaceVariant = Color(0xFFB3B3B3),
|
||||
outline = Color(0xFF333333),
|
||||
outlineVariant = Color(0xFF282828),
|
||||
error = Color(0xFFE22134),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF3D0A0F),
|
||||
onErrorContainer = Color(0xFFFF6B7A)
|
||||
)
|
||||
|
||||
// ── Notion (Clean Dark) ──
|
||||
private val NotionDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF529CCA),
|
||||
onPrimary = Color(0xFF191919),
|
||||
primaryContainer = Color(0xFF2A3A4A),
|
||||
onPrimaryContainer = Color(0xFF7AB8E0),
|
||||
secondary = Color(0xFFE07A5F),
|
||||
onSecondary = Color(0xFF191919),
|
||||
secondaryContainer = Color(0xFF3D2A22),
|
||||
onSecondaryContainer = Color(0xFFF0A08A),
|
||||
tertiary = Color(0xFF81B29A),
|
||||
onTertiary = Color(0xFF191919),
|
||||
background = Color(0xFF191919),
|
||||
onBackground = Color(0xFFE0E0E0),
|
||||
surface = Color(0xFF202020),
|
||||
onSurface = Color(0xFFE0E0E0),
|
||||
surfaceVariant = Color(0xFF2B2B2B),
|
||||
onSurfaceVariant = Color(0xFF9B9B9B),
|
||||
outline = Color(0xFF3E3E3E),
|
||||
outlineVariant = Color(0xFF2F2F2F),
|
||||
error = Color(0xFFEB5757),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF3D1515),
|
||||
onErrorContainer = Color(0xFFFF9B9B)
|
||||
)
|
||||
|
||||
// ── Discord (Blurple Dark) ──
|
||||
private val DiscordDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF5865F2),
|
||||
onPrimary = Color.White,
|
||||
primaryContainer = Color(0xFF3C45A5),
|
||||
onPrimaryContainer = Color(0xFF9BA2FF),
|
||||
secondary = Color(0xFF57F287),
|
||||
onSecondary = Color(0xFF1E2124),
|
||||
secondaryContainer = Color(0xFF234D35),
|
||||
onSecondaryContainer = Color(0xFF7DFFA8),
|
||||
tertiary = Color(0xFFFEE75C),
|
||||
onTertiary = Color(0xFF1E2124),
|
||||
background = Color(0xFF313338),
|
||||
onBackground = Color(0xFFDBDEE1),
|
||||
surface = Color(0xFF2B2D31),
|
||||
onSurface = Color(0xFFDBDEE1),
|
||||
surfaceVariant = Color(0xFF383A40),
|
||||
onSurfaceVariant = Color(0xFFB5BAC1),
|
||||
outline = Color(0xFF4E5058),
|
||||
outlineVariant = Color(0xFF3F4147),
|
||||
error = Color(0xFFED4245),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF4D1516),
|
||||
onErrorContainer = Color(0xFFFFA0A1)
|
||||
)
|
||||
|
||||
// ── Dracula (Iconic Dark) ──
|
||||
private val DraculaDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFFBD93F9),
|
||||
onPrimary = Color(0xFF21222C),
|
||||
primaryContainer = Color(0xFF44475A),
|
||||
onPrimaryContainer = Color(0xFFD6BCFA),
|
||||
secondary = Color(0xFF50FA7B),
|
||||
onSecondary = Color(0xFF21222C),
|
||||
secondaryContainer = Color(0xFF2D4A35),
|
||||
onSecondaryContainer = Color(0xFF7DFFA0),
|
||||
tertiary = Color(0xFFFF79C6),
|
||||
onTertiary = Color(0xFF21222C),
|
||||
background = Color(0xFF282A36),
|
||||
onBackground = Color(0xFFF8F8F2),
|
||||
surface = Color(0xFF21222C),
|
||||
onSurface = Color(0xFFF8F8F2),
|
||||
surfaceVariant = Color(0xFF343746),
|
||||
onSurfaceVariant = Color(0xFFBFBFBF),
|
||||
outline = Color(0xFF6272A4),
|
||||
outlineVariant = Color(0xFF44475A),
|
||||
error = Color(0xFFFF5555),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF4D1A1A),
|
||||
onErrorContainer = Color(0xFFFF9999)
|
||||
)
|
||||
|
||||
// ── One Dark Pro (Atom-inspired) ──
|
||||
private val OneDarkProColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF61AFEF),
|
||||
onPrimary = Color(0xFF1E2127),
|
||||
primaryContainer = Color(0xFF2C3E50),
|
||||
onPrimaryContainer = Color(0xFF8ECBF7),
|
||||
secondary = Color(0xFF98C379),
|
||||
onSecondary = Color(0xFF1E2127),
|
||||
secondaryContainer = Color(0xFF2D3E2A),
|
||||
onSecondaryContainer = Color(0xFFB5D99C),
|
||||
tertiary = Color(0xFFE5C07B),
|
||||
onTertiary = Color(0xFF1E2127),
|
||||
background = Color(0xFF282C34),
|
||||
onBackground = Color(0xFFABB2BF),
|
||||
surface = Color(0xFF21252B),
|
||||
onSurface = Color(0xFFABB2BF),
|
||||
surfaceVariant = Color(0xFF2C313A),
|
||||
onSurfaceVariant = Color(0xFF8B929E),
|
||||
outline = Color(0xFF3E4452),
|
||||
outlineVariant = Color(0xFF333842),
|
||||
error = Color(0xFFE06C75),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF4D2226),
|
||||
onErrorContainer = Color(0xFFF0A0A6)
|
||||
)
|
||||
|
||||
// ── Tokyo Night (Neon Deep Blue) ──
|
||||
private val TokyoNightColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF7AA2F7),
|
||||
onPrimary = Color(0xFF1A1B26),
|
||||
primaryContainer = Color(0xFF2A3A5E),
|
||||
onPrimaryContainer = Color(0xFFA9C1FA),
|
||||
secondary = Color(0xFF9ECE6A),
|
||||
onSecondary = Color(0xFF1A1B26),
|
||||
secondaryContainer = Color(0xFF2D3D24),
|
||||
onSecondaryContainer = Color(0xFFBBE090),
|
||||
tertiary = Color(0xFFBB9AF7),
|
||||
onTertiary = Color(0xFF1A1B26),
|
||||
background = Color(0xFF1A1B26),
|
||||
onBackground = Color(0xFFC0CAF5),
|
||||
surface = Color(0xFF16171F),
|
||||
onSurface = Color(0xFFC0CAF5),
|
||||
surfaceVariant = Color(0xFF24283B),
|
||||
onSurfaceVariant = Color(0xFF9AA5CE),
|
||||
outline = Color(0xFF3B4261),
|
||||
outlineVariant = Color(0xFF292E42),
|
||||
error = Color(0xFFF7768E),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF4D2430),
|
||||
onErrorContainer = Color(0xFFFAA8B6)
|
||||
)
|
||||
|
||||
// ── Nord (Arctic) ──
|
||||
private val NordDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF88C0D0),
|
||||
onPrimary = Color(0xFF2E3440),
|
||||
primaryContainer = Color(0xFF3B4C55),
|
||||
onPrimaryContainer = Color(0xFFA3D4E2),
|
||||
secondary = Color(0xFFA3BE8C),
|
||||
onSecondary = Color(0xFF2E3440),
|
||||
secondaryContainer = Color(0xFF3B4A36),
|
||||
onSecondaryContainer = Color(0xFFBDD4A8),
|
||||
tertiary = Color(0xFFEBCB8B),
|
||||
onTertiary = Color(0xFF2E3440),
|
||||
background = Color(0xFF2E3440),
|
||||
onBackground = Color(0xFFECEFF4),
|
||||
surface = Color(0xFF3B4252),
|
||||
onSurface = Color(0xFFD8DEE9),
|
||||
surfaceVariant = Color(0xFF434C5E),
|
||||
onSurfaceVariant = Color(0xFFD8DEE9),
|
||||
outline = Color(0xFF4C566A),
|
||||
outlineVariant = Color(0xFF434C5E),
|
||||
error = Color(0xFFBF616A),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF4D2528),
|
||||
onErrorContainer = Color(0xFFE09BA1)
|
||||
)
|
||||
|
||||
// ── Night Owl (Accessibility-focused) ──
|
||||
private val NightOwlDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF7FDBCA),
|
||||
onPrimary = Color(0xFF011627),
|
||||
primaryContainer = Color(0xFF1B4A42),
|
||||
onPrimaryContainer = Color(0xFFA0EDDE),
|
||||
secondary = Color(0xFFADDB67),
|
||||
onSecondary = Color(0xFF011627),
|
||||
secondaryContainer = Color(0xFF2D4A1E),
|
||||
onSecondaryContainer = Color(0xFFC8EB8E),
|
||||
tertiary = Color(0xFFC792EA),
|
||||
onTertiary = Color(0xFF011627),
|
||||
background = Color(0xFF011627),
|
||||
onBackground = Color(0xFFD6DEEB),
|
||||
surface = Color(0xFF0B2942),
|
||||
onSurface = Color(0xFFD6DEEB),
|
||||
surfaceVariant = Color(0xFF112B45),
|
||||
onSurfaceVariant = Color(0xFF9FAFC2),
|
||||
outline = Color(0xFF1D3B58),
|
||||
outlineVariant = Color(0xFF15304D),
|
||||
error = Color(0xFFEF5350),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF4D1A19),
|
||||
onErrorContainer = Color(0xFFF7A5A3)
|
||||
)
|
||||
|
||||
// ── Anthracite (Material Design Dark) ──
|
||||
private val AnthraciteDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFFBB86FC),
|
||||
onPrimary = Color(0xFF121212),
|
||||
primaryContainer = Color(0xFF3D2E5C),
|
||||
onPrimaryContainer = Color(0xFFD4AAFD),
|
||||
secondary = Color(0xFF03DAC6),
|
||||
onSecondary = Color(0xFF121212),
|
||||
secondaryContainer = Color(0xFF0A3D38),
|
||||
onSecondaryContainer = Color(0xFF4EEADB),
|
||||
tertiary = Color(0xFFCF6679),
|
||||
onTertiary = Color(0xFF121212),
|
||||
background = Color(0xFF121212),
|
||||
onBackground = Color(0xFFE1E1E1),
|
||||
surface = Color(0xFF1E1E1E),
|
||||
onSurface = Color(0xFFE1E1E1),
|
||||
surfaceVariant = Color(0xFF2C2C2C),
|
||||
onSurfaceVariant = Color(0xFFAAAAAA),
|
||||
outline = Color(0xFF3D3D3D),
|
||||
outlineVariant = Color(0xFF333333),
|
||||
error = Color(0xFFCF6679),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF4D1F27),
|
||||
onErrorContainer = Color(0xFFEFA8B4)
|
||||
)
|
||||
|
||||
// ── Cyberpunk (Neon Futuristic) ──
|
||||
private val CyberpunkDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF00FFFF),
|
||||
onPrimary = Color(0xFF0A0A14),
|
||||
primaryContainer = Color(0xFF0D3D3D),
|
||||
onPrimaryContainer = Color(0xFF66FFFF),
|
||||
secondary = Color(0xFFFF00FF),
|
||||
onSecondary = Color(0xFF0A0A14),
|
||||
secondaryContainer = Color(0xFF3D0D3D),
|
||||
onSecondaryContainer = Color(0xFFFF66FF),
|
||||
tertiary = Color(0xFFFFFF00),
|
||||
onTertiary = Color(0xFF0A0A14),
|
||||
background = Color(0xFF0A0A14),
|
||||
onBackground = Color(0xFFE0E0F0),
|
||||
surface = Color(0xFF12121E),
|
||||
onSurface = Color(0xFFE0E0F0),
|
||||
surfaceVariant = Color(0xFF1A1A2E),
|
||||
onSurfaceVariant = Color(0xFFA0A0C0),
|
||||
outline = Color(0xFF2A2A44),
|
||||
outlineVariant = Color(0xFF1F1F36),
|
||||
error = Color(0xFFFF3366),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF4D0F20),
|
||||
onErrorContainer = Color(0xFFFF8FAB)
|
||||
)
|
||||
|
||||
// ── Navy Elegance (Deep Navy + Gold) ──
|
||||
private val NavyEleganceDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFFD4AF37),
|
||||
onPrimary = Color(0xFF0B1929),
|
||||
primaryContainer = Color(0xFF3D3218),
|
||||
onPrimaryContainer = Color(0xFFE8CC6E),
|
||||
secondary = Color(0xFFC0C0C0),
|
||||
onSecondary = Color(0xFF0B1929),
|
||||
secondaryContainer = Color(0xFF2A2D33),
|
||||
onSecondaryContainer = Color(0xFFD9D9D9),
|
||||
tertiary = Color(0xFF87CEEB),
|
||||
onTertiary = Color(0xFF0B1929),
|
||||
background = Color(0xFF0B1929),
|
||||
onBackground = Color(0xFFE0E4EA),
|
||||
surface = Color(0xFF0F2035),
|
||||
onSurface = Color(0xFFE0E4EA),
|
||||
surfaceVariant = Color(0xFF162A42),
|
||||
onSurfaceVariant = Color(0xFFA0AABB),
|
||||
outline = Color(0xFF1E3550),
|
||||
outlineVariant = Color(0xFF1A2E46),
|
||||
error = Color(0xFFE57373),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF4D2222),
|
||||
onErrorContainer = Color(0xFFF0A8A8)
|
||||
)
|
||||
|
||||
// ── Earthy (Forest & Chocolate) ──
|
||||
private val EarthyDarkColorScheme =
|
||||
darkColorScheme(
|
||||
primary = Color(0xFF81C784),
|
||||
onPrimary = Color(0xFF1A1510),
|
||||
primaryContainer = Color(0xFF2E4A2F),
|
||||
onPrimaryContainer = Color(0xFFA8D8AA),
|
||||
secondary = Color(0xFFD4A574),
|
||||
onSecondary = Color(0xFF1A1510),
|
||||
secondaryContainer = Color(0xFF4A3526),
|
||||
onSecondaryContainer = Color(0xFFE8C49E),
|
||||
tertiary = Color(0xFFA5D6A7),
|
||||
onTertiary = Color(0xFF1A1510),
|
||||
background = Color(0xFF1A1510),
|
||||
onBackground = Color(0xFFE0D8CF),
|
||||
surface = Color(0xFF231E18),
|
||||
onSurface = Color(0xFFE0D8CF),
|
||||
surfaceVariant = Color(0xFF2E2720),
|
||||
onSurfaceVariant = Color(0xFFADA49A),
|
||||
outline = Color(0xFF3D342B),
|
||||
outlineVariant = Color(0xFF332C24),
|
||||
error = Color(0xFFE57373),
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF4D2222),
|
||||
onErrorContainer = Color(0xFFF0A8A8)
|
||||
)
|
||||
|
||||
fun getColorSchemeForTheme(appTheme: AppTheme): androidx.compose.material3.ColorScheme {
|
||||
return when (appTheme) {
|
||||
AppTheme.DEFAULT -> DefaultDarkColorScheme
|
||||
AppTheme.GITHUB -> GitHubDarkColorScheme
|
||||
AppTheme.LINEAR -> LinearDarkColorScheme
|
||||
AppTheme.SPOTIFY -> SpotifyDarkColorScheme
|
||||
AppTheme.NOTION -> NotionDarkColorScheme
|
||||
AppTheme.DISCORD -> DiscordDarkColorScheme
|
||||
AppTheme.DRACULA -> DraculaDarkColorScheme
|
||||
AppTheme.ONE_DARK_PRO -> OneDarkProColorScheme
|
||||
AppTheme.TOKYO_NIGHT -> TokyoNightColorScheme
|
||||
AppTheme.NORD -> NordDarkColorScheme
|
||||
AppTheme.NIGHT_OWL -> NightOwlDarkColorScheme
|
||||
AppTheme.ANTHRACITE -> AnthraciteDarkColorScheme
|
||||
AppTheme.CYBERPUNK -> CyberpunkDarkColorScheme
|
||||
AppTheme.NAVY_ELEGANCE -> NavyEleganceDarkColorScheme
|
||||
AppTheme.EARTHY -> EarthyDarkColorScheme
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ShaarItTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
dynamicColor: Boolean = true, // Enable Material You by default
|
||||
oledMode: Boolean = false, // Pure black for OLED screens
|
||||
appTheme: AppTheme = AppTheme.DEFAULT,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
// Always use the explicit color scheme for the selected theme
|
||||
val colorScheme = getColorSchemeForTheme(appTheme)
|
||||
|
||||
val colorScheme =
|
||||
when {
|
||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||
// Material You (Monet) - dynamic colors from wallpaper
|
||||
if (darkTheme) {
|
||||
if (oledMode) {
|
||||
// OLED pure black variant
|
||||
dynamicDarkColorScheme(context).copy(
|
||||
background = Color.Black,
|
||||
surface = Color(0xFF0A0A0A),
|
||||
surfaceVariant = Color(0xFF1A1A1A)
|
||||
)
|
||||
} else {
|
||||
dynamicDarkColorScheme(context)
|
||||
}
|
||||
} else {
|
||||
dynamicLightColorScheme(context)
|
||||
}
|
||||
}
|
||||
darkTheme -> {
|
||||
if (oledMode) {
|
||||
// OLED pure black variant of custom theme
|
||||
DarkColorScheme.copy(
|
||||
background = Color.Black,
|
||||
surface = Color(0xFF0A0A0A),
|
||||
surfaceVariant = Color(0xFF1A1A1A)
|
||||
)
|
||||
} else {
|
||||
DarkColorScheme
|
||||
}
|
||||
}
|
||||
else -> LightColorScheme
|
||||
}
|
||||
// All custom themes are dark
|
||||
val isEffectivelyDark = true
|
||||
|
||||
val view = LocalView.current
|
||||
if (!view.isInEditMode) {
|
||||
@ -138,7 +483,7 @@ fun ShaarItTheme(
|
||||
val window = (view.context as Activity).window
|
||||
window.statusBarColor = colorScheme.background.toArgb()
|
||||
window.navigationBarColor = colorScheme.background.toArgb()
|
||||
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
|
||||
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !isEffectivelyDark
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user