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:
Bruno Charest 2026-02-09 12:56:33 -05:00
parent 80ab3009aa
commit 98f2ef2e7e
17 changed files with 1116 additions and 526 deletions

View File

@ -8,18 +8,25 @@ import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import com.shaarit.presentation.nav.AppNavGraph import com.shaarit.presentation.nav.AppNavGraph
import com.shaarit.ui.theme.ShaarItTheme import com.shaarit.ui.theme.ShaarItTheme
import com.shaarit.ui.theme.ThemePreferences
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import java.io.BufferedReader import java.io.BufferedReader
import java.io.InputStreamReader import java.io.InputStreamReader
import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@Inject lateinit var themePreferences: ThemePreferences
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
// Install splash screen before super.onCreate // Install splash screen before super.onCreate
installSplashScreen() installSplashScreen()
@ -31,7 +38,8 @@ class MainActivity : ComponentActivity() {
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
setContent { setContent {
ShaarItTheme { val currentTheme by themePreferences.currentTheme.collectAsState()
ShaarItTheme(appTheme = currentTheme) {
// A surface container using the 'background' color from the theme // A surface container using the 'background' color from the theme
val context = LocalContext.current val context = LocalContext.current
var shareUrl: String? = null var shareUrl: String? = null

View File

@ -34,8 +34,7 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.shaarit.ui.components.* import com.shaarit.ui.components.*
import com.shaarit.ui.theme.* import com.shaarit.ui.theme.Typography
import com.shaarit.ui.theme.Purple
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class, androidx.compose.foundation.ExperimentalFoundationApi::class) @OptIn(ExperimentalMaterial3Api::class, androidx.compose.foundation.ExperimentalFoundationApi::class)
@ -109,37 +108,37 @@ fun AddLinkScreen(
AlertDialog( AlertDialog(
onDismissRequest = { viewModel.dismissConflict() }, onDismissRequest = { viewModel.dismissConflict() },
title = { title = {
Text("Lien déjà existant", fontWeight = FontWeight.Bold, color = TextPrimary) Text("Lien déjà existant", fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.onBackground)
}, },
text = { text = {
Column { 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)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
conflict.existingTitle ?: "Sans titre", conflict.existingTitle ?: "Sans titre",
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium
) )
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
Text( Text(
"Voulez-vous mettre à jour le lien existant?", "Voulez-vous mettre à jour le lien existant?",
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
}, },
confirmButton = { confirmButton = {
TextButton(onClick = { viewModel.forceUpdateExistingLink() }) { TextButton(onClick = { viewModel.forceUpdateExistingLink() }) {
Text("Mettre à jour", color = CyanPrimary) Text("Mettre à jour", color = MaterialTheme.colorScheme.primary)
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = { viewModel.dismissConflict() }) { TextButton(onClick = { viewModel.dismissConflict() }) {
Text("Annuler", color = TextMuted) Text("Annuler", color = MaterialTheme.colorScheme.outline)
} }
}, },
containerColor = CardBackground, containerColor = MaterialTheme.colorScheme.surfaceVariant,
titleContentColor = TextPrimary, titleContentColor = MaterialTheme.colorScheme.onBackground,
textContentColor = TextSecondary textContentColor = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
@ -147,7 +146,7 @@ fun AddLinkScreen(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background( .background(
brush = Brush.verticalGradient(colors = listOf(DeepNavy, DarkNavy)) brush = Brush.verticalGradient(colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface))
) )
) { ) {
// Contenu principal avec Scaffold // Contenu principal avec Scaffold
@ -167,13 +166,13 @@ fun AddLinkScreen(
Icon( Icon(
Icons.Default.ArrowBack, Icons.Default.ArrowBack,
contentDescription = "Retour", contentDescription = "Retour",
tint = TextPrimary tint = MaterialTheme.colorScheme.onBackground
) )
} }
}, },
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = DeepNavy.copy(alpha = 0.9f), containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
titleContentColor = TextPrimary titleContentColor = MaterialTheme.colorScheme.onBackground
) )
) )
}, },
@ -191,7 +190,7 @@ fun AddLinkScreen(
// Content Type Selection (compact) // Content Type Selection (compact)
GlassCard( GlassCard(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
glowColor = CyanPrimary glowColor = MaterialTheme.colorScheme.primary
) { ) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -236,14 +235,14 @@ fun AddLinkScreen(
value = url, value = url,
onValueChange = { viewModel.url.value = it }, onValueChange = { viewModel.url.value = it },
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
placeholder = { Text("https://example.com", color = TextMuted) }, placeholder = { Text("https://example.com", color = MaterialTheme.colorScheme.outline) },
singleLine = true, singleLine = true,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
trailingIcon = { trailingIcon = {
if (isExtractingMetadata) { if (isExtractingMetadata) {
CircularProgressIndicator( CircularProgressIndicator(
modifier = Modifier.size(18.dp), modifier = Modifier.size(18.dp),
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
strokeWidth = 2.dp strokeWidth = 2.dp
) )
} }
@ -288,14 +287,14 @@ fun AddLinkScreen(
else -> Icons.Default.Web else -> Icons.Default.Web
}, },
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(
text = type, text = type,
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -329,7 +328,7 @@ fun AddLinkScreen(
Text( Text(
if (contentTypeSelection == ContentType.NOTE) if (contentTypeSelection == ContentType.NOTE)
"Titre de la note" else "Titre du lien", "Titre de la note" else "Titre du lien",
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
}, },
singleLine = true, singleLine = true,
@ -365,7 +364,7 @@ fun AddLinkScreen(
Icon( Icon(
imageVector = Icons.Default.Description, imageVector = Icons.Default.Description,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
Column { Column {
@ -374,13 +373,13 @@ fun AddLinkScreen(
"Contenu" else "Description", "Contenu" else "Description",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
if (contentTypeSelection == ContentType.NOTE) { if (contentTypeSelection == ContentType.NOTE) {
Text( Text(
text = "Markdown supporté", text = "Markdown supporté",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
} }
} }
@ -397,7 +396,7 @@ fun AddLinkScreen(
Icon( Icon(
Icons.Default.Edit, Icons.Default.Edit,
contentDescription = "Éditer", contentDescription = "Éditer",
tint = if (!showMarkdownPreview) CyanPrimary else TextMuted, tint = if (!showMarkdownPreview) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
} }
@ -408,7 +407,7 @@ fun AddLinkScreen(
Icon( Icon(
Icons.Default.Preview, Icons.Default.Preview,
contentDescription = "Aperçu", contentDescription = "Aperçu",
tint = if (showMarkdownPreview) CyanPrimary else TextMuted, tint = if (showMarkdownPreview) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
} }
@ -463,14 +462,14 @@ fun AddLinkScreen(
Icon( Icon(
imageVector = Icons.Default.Tag, imageVector = Icons.Default.Tag,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
Text( Text(
text = "Tags", text = "Tags",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold, 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, singleLine = true,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions( keyboardActions = KeyboardActions(
@ -537,7 +536,7 @@ fun AddLinkScreen(
Icon( Icon(
Icons.Default.Add, Icons.Default.Add,
contentDescription = "Ajouter", 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( Text(
"Suggestions", "Suggestions",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
modifier = Modifier.padding(bottom = 8.dp) modifier = Modifier.padding(bottom = 8.dp)
) )
LazyRow( LazyRow(
@ -579,7 +578,7 @@ fun AddLinkScreen(
Text( Text(
"Populaires", "Populaires",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
modifier = Modifier.padding(bottom = 8.dp) modifier = Modifier.padding(bottom = 8.dp)
) )
LazyRow( LazyRow(
@ -617,16 +616,16 @@ fun AddLinkScreen(
Text( Text(
if (isPrivate) "Seul vous pouvez voir" else "Visible par tous", if (isPrivate) "Seul vous pouvez voir" else "Visible par tous",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
Switch( Switch(
checked = isPrivate, checked = isPrivate,
onCheckedChange = { viewModel.isPrivate.value = it }, onCheckedChange = { viewModel.isPrivate.value = it },
colors = SwitchDefaults.colors( colors = SwitchDefaults.colors(
checkedThumbColor = CyanPrimary, checkedThumbColor = MaterialTheme.colorScheme.primary,
checkedTrackColor = CyanPrimary.copy(alpha = 0.3f), checkedTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f),
uncheckedThumbColor = TextMuted, uncheckedThumbColor = MaterialTheme.colorScheme.outline,
uncheckedTrackColor = SurfaceVariant uncheckedTrackColor = MaterialTheme.colorScheme.outlineVariant
) )
) )
} }
@ -652,8 +651,8 @@ fun AddLinkScreen(
if (uiState is AddLinkUiState.Loading) { if (uiState is AddLinkUiState.Loading) {
LinearProgressIndicator( LinearProgressIndicator(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
trackColor = SurfaceVariant trackColor = MaterialTheme.colorScheme.outlineVariant
) )
} }
@ -685,8 +684,8 @@ private fun ContentTypeButton(
Surface( Surface(
onClick = onClick, onClick = onClick,
shape = RoundedCornerShape(10.dp), shape = RoundedCornerShape(10.dp),
color = if (isSelected) CyanPrimary.copy(alpha = 0.15f) else CardBackgroundElevated, color = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.15f) else MaterialTheme.colorScheme.primaryContainer,
border = if (isSelected) androidx.compose.foundation.BorderStroke(1.5.dp, CyanPrimary) else null, border = if (isSelected) androidx.compose.foundation.BorderStroke(1.5.dp, MaterialTheme.colorScheme.primary) else null,
modifier = modifier modifier = modifier
) { ) {
Row( Row(
@ -697,14 +696,14 @@ private fun ContentTypeButton(
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
tint = if (isSelected) CyanPrimary else TextSecondary, tint = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(
text = label, text = label,
style = MaterialTheme.typography.bodyMedium, 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 fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal
) )
} }
@ -731,7 +730,7 @@ private fun CompactFieldCard(
GlassCard( GlassCard(
modifier = finalModifier, modifier = finalModifier,
glowColor = CyanPrimary.copy(alpha = 0.3f) glowColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f)
) { ) {
Column { Column {
Row( Row(
@ -742,13 +741,13 @@ private fun CompactFieldCard(
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
Text( Text(
text = label, text = label,
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = TextSecondary, color = MaterialTheme.colorScheme.onSurfaceVariant,
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium
) )
} }
@ -763,13 +762,13 @@ private fun CompactFieldCard(
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun compactTextFieldColors() = OutlinedTextFieldDefaults.colors( private fun compactTextFieldColors() = OutlinedTextFieldDefaults.colors(
focusedBorderColor = CyanPrimary, focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = SurfaceVariant, unfocusedBorderColor = MaterialTheme.colorScheme.outlineVariant,
focusedLabelColor = CyanPrimary, focusedLabelColor = MaterialTheme.colorScheme.primary,
unfocusedLabelColor = TextSecondary, unfocusedLabelColor = MaterialTheme.colorScheme.onSurfaceVariant,
cursorColor = CyanPrimary, cursorColor = MaterialTheme.colorScheme.primary,
focusedContainerColor = CardBackground.copy(alpha = 0.3f), focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f),
unfocusedContainerColor = CardBackground.copy(alpha = 0.2f) unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.2f)
) )
/** /**
@ -797,8 +796,8 @@ private fun AiMagicButton(
onClick = onClick, onClick = onClick,
enabled = enabled && !isLoading, enabled = enabled && !isLoading,
shape = RoundedCornerShape(10.dp), shape = RoundedCornerShape(10.dp),
color = if (enabled) Purple.copy(alpha = if (isLoading) shimmerAlpha * 0.3f else 0.15f) else SurfaceVariant, 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, Purple) else null, border = if (enabled) androidx.compose.foundation.BorderStroke(1.5.dp, MaterialTheme.colorScheme.tertiary) else null,
modifier = modifier.size(48.dp) modifier = modifier.size(48.dp)
) { ) {
Box( Box(
@ -808,14 +807,14 @@ private fun AiMagicButton(
if (isLoading) { if (isLoading) {
CircularProgressIndicator( CircularProgressIndicator(
modifier = Modifier.size(20.dp), modifier = Modifier.size(20.dp),
color = Purple, color = MaterialTheme.colorScheme.tertiary,
strokeWidth = 2.dp strokeWidth = 2.dp
) )
} else { } else {
Icon( Icon(
imageVector = Icons.Outlined.AutoAwesome, imageVector = Icons.Outlined.AutoAwesome,
contentDescription = "Magie IA", contentDescription = "Magie IA",
tint = if (enabled) Purple else TextMuted, tint = if (enabled) MaterialTheme.colorScheme.tertiary else MaterialTheme.colorScheme.outline,
modifier = Modifier.size(22.dp) modifier = Modifier.size(22.dp)
) )
} }

View File

@ -19,7 +19,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import com.shaarit.ui.components.GlassCard import com.shaarit.ui.components.GlassCard
import com.shaarit.ui.components.GradientButton import com.shaarit.ui.components.GradientButton
import com.shaarit.ui.components.PremiumTextField import com.shaarit.ui.components.PremiumTextField
import com.shaarit.ui.theme.* import com.shaarit.ui.theme.Typography
@Composable @Composable
fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltViewModel()) { fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltViewModel()) {
@ -58,7 +58,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
.background( .background(
brush = brush =
Brush.verticalGradient( 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( Brush.radialGradient(
colors = colors =
listOf( listOf(
CyanPrimary.copy( MaterialTheme.colorScheme.primary.copy(
alpha = alpha =
backgroundAlpha backgroundAlpha
), ),
@ -110,13 +110,13 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
text = "ShaarIt", text = "ShaarIt",
style = MaterialTheme.typography.displayMedium, style = MaterialTheme.typography.displayMedium,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
text = "Your personal bookmark manager", text = "Your personal bookmark manager",
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
color = TextSecondary, color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
} }
@ -131,7 +131,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
text = "Connect to Shaarli", text = "Connect to Shaarli",
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
PremiumTextField( PremiumTextField(
@ -154,7 +154,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
Icon( Icon(
Icons.Default.Lock, Icons.Default.Lock,
contentDescription = null, contentDescription = null,
tint = TextMuted tint = MaterialTheme.colorScheme.outline
) )
}, },
trailingIcon = { trailingIcon = {
@ -162,7 +162,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
Text( Text(
if (showSecret) "Hide" else "Show", if (showSecret) "Hide" else "Show",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
} }
} }
@ -174,7 +174,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
Box( Box(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { CircularProgressIndicator(color = CyanPrimary) } ) { CircularProgressIndicator(color = MaterialTheme.colorScheme.primary) }
} else { } else {
GradientButton( GradientButton(
text = "Connect", text = "Connect",
@ -192,7 +192,7 @@ fun LoginScreen(onLoginSuccess: () -> Unit, viewModel: LoginViewModel = hiltView
text = text =
"Find your API secret in Shaarli's\n\"Tools\"\"Configure your Shaarli\"", "Find your API secret in Shaarli's\n\"Tools\"\"Configure your Shaarli\"",
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.alpha(0.7f) modifier = Modifier.alpha(0.7f)
) )

View File

@ -27,7 +27,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import com.shaarit.ui.components.GlassCard import com.shaarit.ui.components.GlassCard
import com.shaarit.ui.theme.* import com.shaarit.ui.theme.Typography
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -47,7 +47,7 @@ fun CollectionsScreen(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background( .background(
brush = Brush.verticalGradient(colors = listOf(DeepNavy, DarkNavy)) brush = Brush.verticalGradient(colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface))
) )
) { ) {
Scaffold( Scaffold(
@ -65,7 +65,7 @@ fun CollectionsScreen(
Icon( Icon(
Icons.Default.ArrowBack, Icons.Default.ArrowBack,
contentDescription = "Retour", contentDescription = "Retour",
tint = TextPrimary tint = MaterialTheme.colorScheme.onBackground
) )
} }
}, },
@ -74,13 +74,13 @@ fun CollectionsScreen(
Icon( Icon(
Icons.Default.Add, Icons.Default.Add,
contentDescription = "Nouvelle collection", contentDescription = "Nouvelle collection",
tint = CyanPrimary tint = MaterialTheme.colorScheme.primary
) )
} }
}, },
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = DeepNavy.copy(alpha = 0.9f), containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
titleContentColor = TextPrimary titleContentColor = MaterialTheme.colorScheme.onBackground
) )
) )
}, },
@ -88,8 +88,8 @@ fun CollectionsScreen(
floatingActionButton = { floatingActionButton = {
FloatingActionButton( FloatingActionButton(
onClick = { showCreateDialog = true }, onClick = { showCreateDialog = true },
containerColor = CyanPrimary, containerColor = MaterialTheme.colorScheme.primary,
contentColor = DeepNavy contentColor = MaterialTheme.colorScheme.background
) { ) {
Icon(Icons.Default.Add, contentDescription = "Nouvelle collection") Icon(Icons.Default.Add, contentDescription = "Nouvelle collection")
} }
@ -103,7 +103,7 @@ fun CollectionsScreen(
if (isLoading) { if (isLoading) {
CircularProgressIndicator( CircularProgressIndicator(
modifier = Modifier.align(Alignment.Center), modifier = Modifier.align(Alignment.Center),
color = CyanPrimary color = MaterialTheme.colorScheme.primary
) )
} else if (collections.isEmpty()) { } else if (collections.isEmpty()) {
EmptyCollectionsView(onCreateClick = { showCreateDialog = true }) EmptyCollectionsView(onCreateClick = { showCreateDialog = true })
@ -170,7 +170,7 @@ fun CollectionsScreen(
showDeleteConfirm = null showDeleteConfirm = null
}, },
colors = ButtonDefaults.textButtonColors( colors = ButtonDefaults.textButtonColors(
contentColor = ErrorRed contentColor = MaterialTheme.colorScheme.error
) )
) { ) {
Text("Supprimer") Text("Supprimer")
@ -181,9 +181,9 @@ fun CollectionsScreen(
Text("Annuler") Text("Annuler")
} }
}, },
containerColor = CardBackground, containerColor = MaterialTheme.colorScheme.surfaceVariant,
titleContentColor = TextPrimary, titleContentColor = MaterialTheme.colorScheme.onBackground,
textContentColor = TextSecondary textContentColor = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -226,7 +226,7 @@ private fun CollectionCard(
Icon( Icon(
imageVector = Icons.Default.AutoAwesome, imageVector = Icons.Default.AutoAwesome,
contentDescription = "Collection intelligente", contentDescription = "Collection intelligente",
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
} }
@ -238,7 +238,7 @@ private fun CollectionCard(
text = collection.name, text = collection.name,
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = TextPrimary, color = MaterialTheme.colorScheme.onBackground,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -248,7 +248,7 @@ private fun CollectionCard(
Text( Text(
text = desc, text = desc,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = TextSecondary, color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(top = 4.dp) modifier = Modifier.padding(top = 4.dp)
@ -260,7 +260,7 @@ private fun CollectionCard(
Text( Text(
text = "${collection.linkCount} lien${if (collection.linkCount > 1) "s" else ""}", text = "${collection.linkCount} lien${if (collection.linkCount > 1) "s" else ""}",
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
modifier = Modifier.padding(top = 8.dp) modifier = Modifier.padding(top = 8.dp)
) )
} }
@ -279,7 +279,7 @@ private fun CollectionCard(
Icon( Icon(
imageVector = Icons.Default.MoreVert, imageVector = Icons.Default.MoreVert,
contentDescription = "Options", contentDescription = "Options",
tint = TextSecondary, tint = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
} }
@ -287,7 +287,7 @@ private fun CollectionCard(
DropdownMenu( DropdownMenu(
expanded = showMenu, expanded = showMenu,
onDismissRequest = { showMenu = false }, onDismissRequest = { showMenu = false },
modifier = Modifier.background(CardBackground) modifier = Modifier.background(MaterialTheme.colorScheme.surfaceVariant)
) { ) {
DropdownMenuItem( DropdownMenuItem(
text = { text = {
@ -298,10 +298,10 @@ private fun CollectionCard(
Icon( Icon(
Icons.Default.Edit, Icons.Default.Edit,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
Text("Modifier", color = TextPrimary) Text("Modifier", color = MaterialTheme.colorScheme.onBackground)
} }
}, },
onClick = { onClick = {
@ -318,10 +318,10 @@ private fun CollectionCard(
Icon( Icon(
Icons.Default.Delete, Icons.Default.Delete,
contentDescription = null, contentDescription = null,
tint = ErrorRed, tint = MaterialTheme.colorScheme.error,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
Text("Supprimer", color = ErrorRed) Text("Supprimer", color = MaterialTheme.colorScheme.error)
} }
}, },
onClick = { onClick = {
@ -347,7 +347,7 @@ private fun EmptyCollectionsView(onCreateClick: () -> Unit) {
Icon( Icon(
imageVector = Icons.Default.FolderOpen, imageVector = Icons.Default.FolderOpen,
contentDescription = null, contentDescription = null,
tint = TextMuted, tint = MaterialTheme.colorScheme.outline,
modifier = Modifier.size(80.dp) modifier = Modifier.size(80.dp)
) )
@ -357,7 +357,7 @@ private fun EmptyCollectionsView(onCreateClick: () -> Unit) {
text = "Aucune collection", text = "Aucune collection",
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@ -365,7 +365,7 @@ private fun EmptyCollectionsView(onCreateClick: () -> Unit) {
Text( Text(
text = "Créez des collections pour organiser vos liens par thème", text = "Créez des collections pour organiser vos liens par thème",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextSecondary, color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = androidx.compose.ui.text.style.TextAlign.Center textAlign = androidx.compose.ui.text.style.TextAlign.Center
) )
@ -374,8 +374,8 @@ private fun EmptyCollectionsView(onCreateClick: () -> Unit) {
Button( Button(
onClick = onCreateClick, onClick = onCreateClick,
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = CyanPrimary, containerColor = MaterialTheme.colorScheme.primary,
contentColor = DeepNavy contentColor = MaterialTheme.colorScheme.background
) )
) { ) {
Icon(Icons.Default.Add, contentDescription = null) Icon(Icons.Default.Add, contentDescription = null)
@ -443,11 +443,11 @@ private fun CollectionDialogContent(
AlertDialog( AlertDialog(
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
containerColor = CardBackground, containerColor = MaterialTheme.colorScheme.surfaceVariant,
title = { title = {
Text( Text(
title, title,
color = TextPrimary, color = MaterialTheme.colorScheme.onBackground,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
}, },
@ -463,14 +463,14 @@ private fun CollectionDialogContent(
OutlinedTextField( OutlinedTextField(
value = name, value = name,
onValueChange = { name = it }, onValueChange = { name = it },
label = { Text("Nom", color = TextSecondary) }, label = { Text("Nom", color = MaterialTheme.colorScheme.onSurfaceVariant) },
singleLine = true, singleLine = true,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
colors = OutlinedTextFieldDefaults.colors( colors = OutlinedTextFieldDefaults.colors(
focusedBorderColor = CyanPrimary, focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = TextMuted, unfocusedBorderColor = MaterialTheme.colorScheme.outline,
focusedTextColor = TextPrimary, focusedTextColor = MaterialTheme.colorScheme.onBackground,
unfocusedTextColor = TextPrimary unfocusedTextColor = MaterialTheme.colorScheme.onBackground
) )
) )
@ -478,15 +478,15 @@ private fun CollectionDialogContent(
OutlinedTextField( OutlinedTextField(
value = description, value = description,
onValueChange = { description = it }, onValueChange = { description = it },
label = { Text("Description (optionnel)", color = TextSecondary) }, label = { Text("Description (optionnel)", color = MaterialTheme.colorScheme.onSurfaceVariant) },
minLines = 2, minLines = 2,
maxLines = 3, maxLines = 3,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
colors = OutlinedTextFieldDefaults.colors( colors = OutlinedTextFieldDefaults.colors(
focusedBorderColor = CyanPrimary, focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = TextMuted, unfocusedBorderColor = MaterialTheme.colorScheme.outline,
focusedTextColor = TextPrimary, focusedTextColor = MaterialTheme.colorScheme.onBackground,
unfocusedTextColor = TextPrimary unfocusedTextColor = MaterialTheme.colorScheme.onBackground
) )
) )
@ -494,7 +494,7 @@ private fun CollectionDialogContent(
Text( Text(
"Icône", "Icône",
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
FlowRow( FlowRow(
horizontalArrangement = Arrangement.spacedBy(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp),
@ -507,12 +507,12 @@ private fun CollectionDialogContent(
.size(44.dp) .size(44.dp)
.clip(RoundedCornerShape(10.dp)) .clip(RoundedCornerShape(10.dp))
.background( .background(
if (isSelected) CyanPrimary.copy(alpha = 0.2f) if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.2f)
else CardBackgroundElevated else MaterialTheme.colorScheme.surfaceVariant
) )
.border( .border(
width = if (isSelected) 2.dp else 0.dp, 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) shape = RoundedCornerShape(10.dp)
) )
.clickable { selectedIcon = icon }, .clickable { selectedIcon = icon },
@ -527,10 +527,10 @@ private fun CollectionDialogContent(
Card( Card(
onClick = { isSmart = !isSmart }, onClick = { isSmart = !isSmart },
colors = CardDefaults.cardColors( 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) { 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, } else null,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
@ -548,19 +548,19 @@ private fun CollectionDialogContent(
Icon( Icon(
imageVector = Icons.Default.AutoAwesome, imageVector = Icons.Default.AutoAwesome,
contentDescription = null, contentDescription = null,
tint = if (isSmart) CyanPrimary else TextSecondary tint = if (isSmart) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
) )
Column(modifier = Modifier.weight(1f)) { Column(modifier = Modifier.weight(1f)) {
Text( Text(
"Collection intelligente", "Collection intelligente",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextPrimary, color = MaterialTheme.colorScheme.onBackground,
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium
) )
Text( Text(
"Remplie automatiquement selon les tags sélectionnés", "Remplie automatiquement selon les tags sélectionnés",
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -568,8 +568,8 @@ private fun CollectionDialogContent(
checked = isSmart, checked = isSmart,
onCheckedChange = { isSmart = it }, onCheckedChange = { isSmart = it },
colors = SwitchDefaults.colors( colors = SwitchDefaults.colors(
checkedThumbColor = CyanPrimary, checkedThumbColor = MaterialTheme.colorScheme.primary,
checkedTrackColor = CyanPrimary.copy(alpha = 0.5f) checkedTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.5f)
) )
) )
} }
@ -581,7 +581,7 @@ private fun CollectionDialogContent(
Text( Text(
"Tags sélectionnés (${selectedTags.size})", "Tags sélectionnés (${selectedTags.size})",
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
FlowRow( FlowRow(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -608,22 +608,22 @@ private fun CollectionDialogContent(
tagSearch = it tagSearch = it
showTagDropdown = it.isNotBlank() || tags.isNotEmpty() showTagDropdown = it.isNotBlank() || tags.isNotEmpty()
}, },
label = { Text("Ajouter des tags...", color = TextSecondary) }, label = { Text("Ajouter des tags...", color = MaterialTheme.colorScheme.onSurfaceVariant) },
singleLine = true, singleLine = true,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.menuAnchor(), .menuAnchor(),
colors = OutlinedTextFieldDefaults.colors( colors = OutlinedTextFieldDefaults.colors(
focusedBorderColor = CyanPrimary, focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = TextMuted, unfocusedBorderColor = MaterialTheme.colorScheme.outline,
focusedTextColor = TextPrimary, focusedTextColor = MaterialTheme.colorScheme.onBackground,
unfocusedTextColor = TextPrimary unfocusedTextColor = MaterialTheme.colorScheme.onBackground
), ),
trailingIcon = { trailingIcon = {
Icon( Icon(
imageVector = if (showTagDropdown) Icons.Default.ExpandLess else Icons.Default.ExpandMore, imageVector = if (showTagDropdown) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
contentDescription = null, contentDescription = null,
tint = TextSecondary tint = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
) )
@ -643,7 +643,7 @@ private fun CollectionDialogContent(
expanded = showTagDropdown, expanded = showTagDropdown,
onDismissRequest = { showTagDropdown = false }, onDismissRequest = { showTagDropdown = false },
modifier = Modifier modifier = Modifier
.background(CardBackgroundElevated) .background(MaterialTheme.colorScheme.primaryContainer)
.heightIn(max = 250.dp) .heightIn(max = 250.dp)
) { ) {
availableTags.forEach { tag -> availableTags.forEach { tag ->
@ -651,7 +651,7 @@ private fun CollectionDialogContent(
text = { text = {
Text( Text(
"#$tag", "#$tag",
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
}, },
onClick = { onClick = {
@ -663,7 +663,7 @@ private fun CollectionDialogContent(
Icon( Icon(
imageVector = Icons.Default.Add, imageVector = Icons.Default.Add,
contentDescription = null, contentDescription = null,
tint = CyanPrimary tint = MaterialTheme.colorScheme.primary
) )
} }
) )
@ -683,7 +683,7 @@ private fun CollectionDialogContent(
Text( Text(
"Tags populaires", "Tags populaires",
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
FlowRow( FlowRow(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -709,8 +709,8 @@ private fun CollectionDialogContent(
}, },
enabled = name.isNotBlank() && (!isSmart || selectedTags.isNotEmpty()), enabled = name.isNotBlank() && (!isSmart || selectedTags.isNotEmpty()),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = CyanPrimary, containerColor = MaterialTheme.colorScheme.primary,
contentColor = DeepNavy contentColor = MaterialTheme.colorScheme.background
) )
) { ) {
Text(if (isEdit) "Enregistrer" else "Créer") Text(if (isEdit) "Enregistrer" else "Créer")
@ -718,7 +718,7 @@ private fun CollectionDialogContent(
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismiss) { TextButton(onClick = onDismiss) {
Text("Annuler", color = TextSecondary) Text("Annuler", color = MaterialTheme.colorScheme.onSurfaceVariant)
} }
} }
) )
@ -731,8 +731,8 @@ private fun SelectedTagChip(
) { ) {
Surface( Surface(
shape = MaterialTheme.shapes.small, shape = MaterialTheme.shapes.small,
color = CyanPrimary.copy(alpha = 0.2f), color = MaterialTheme.colorScheme.primary.copy(alpha = 0.2f),
border = androidx.compose.foundation.BorderStroke(1.dp, CyanPrimary.copy(alpha = 0.5f)) border = androidx.compose.foundation.BorderStroke(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.5f))
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@ -741,7 +741,7 @@ private fun SelectedTagChip(
Text( Text(
text = "#$tag", text = "#$tag",
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = CyanLight color = MaterialTheme.colorScheme.tertiary
) )
IconButton( IconButton(
onClick = onRemove, onClick = onRemove,
@ -750,7 +750,7 @@ private fun SelectedTagChip(
Icon( Icon(
imageVector = Icons.Default.Close, imageVector = Icons.Default.Close,
contentDescription = "Retirer", contentDescription = "Retirer",
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(14.dp) modifier = Modifier.size(14.dp)
) )
} }
@ -766,7 +766,7 @@ private fun AvailableTagChip(
Surface( Surface(
onClick = onClick, onClick = onClick,
shape = MaterialTheme.shapes.small, shape = MaterialTheme.shapes.small,
color = CardBackground color = MaterialTheme.colorScheme.surfaceVariant
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@ -775,14 +775,14 @@ private fun AvailableTagChip(
Icon( Icon(
imageVector = Icons.Default.Add, imageVector = Icons.Default.Add,
contentDescription = null, contentDescription = null,
tint = TextMuted, tint = MaterialTheme.colorScheme.outline,
modifier = Modifier.size(14.dp) modifier = Modifier.size(14.dp)
) )
Spacer(modifier = Modifier.width(4.dp)) Spacer(modifier = Modifier.width(4.dp))
Text( Text(
text = "#$tag", text = "#$tag",
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }

View File

@ -26,7 +26,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.paging.LoadState import androidx.paging.LoadState
import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems
import com.shaarit.presentation.feed.ListViewItem import com.shaarit.presentation.feed.ListViewItem
import com.shaarit.ui.theme.* import com.shaarit.ui.theme.Typography
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -46,7 +46,7 @@ fun DeadLinksScreen(
.fillMaxSize() .fillMaxSize()
.background( .background(
brush = Brush.verticalGradient( 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", if (isSelectionMode) "${selectedLinkIds.size} sélectionné(s)" else "Liens inaccessibles",
style = MaterialTheme.typography.headlineSmall, style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
}, },
navigationIcon = { navigationIcon = {
@ -73,7 +73,7 @@ fun DeadLinksScreen(
Icon( Icon(
if (isSelectionMode) Icons.Default.Close else Icons.Default.ArrowBack, if (isSelectionMode) Icons.Default.Close else Icons.Default.ArrowBack,
contentDescription = if (isSelectionMode) "Annuler" else "Retour", contentDescription = if (isSelectionMode) "Annuler" else "Retour",
tint = TextPrimary tint = MaterialTheme.colorScheme.onBackground
) )
} }
}, },
@ -87,14 +87,14 @@ fun DeadLinksScreen(
Icon( Icon(
imageVector = Icons.Default.CheckCircle, imageVector = Icons.Default.CheckCircle,
contentDescription = "Exclure de la vérification", contentDescription = "Exclure de la vérification",
tint = SuccessGreen tint = Color(0xFF10B981)
) )
} }
} }
}, },
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = DeepNavy.copy(alpha = 0.9f), containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
titleContentColor = TextPrimary titleContentColor = MaterialTheme.colorScheme.onBackground
) )
) )
}, },
@ -107,7 +107,7 @@ fun DeadLinksScreen(
) { ) {
if (pagingItems.loadState.refresh is LoadState.Loading && pagingItems.itemCount == 0) { if (pagingItems.loadState.refresh is LoadState.Loading && pagingItems.itemCount == 0) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CircularProgressIndicator(color = CyanPrimary) CircularProgressIndicator(color = MaterialTheme.colorScheme.primary)
} }
} else if (pagingItems.itemCount == 0) { } else if (pagingItems.itemCount == 0) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
@ -115,19 +115,19 @@ fun DeadLinksScreen(
Icon( Icon(
imageVector = Icons.Default.BrokenImage, imageVector = Icons.Default.BrokenImage,
contentDescription = null, contentDescription = null,
tint = TextMuted, tint = MaterialTheme.colorScheme.outline,
modifier = Modifier.size(64.dp) modifier = Modifier.size(64.dp)
) )
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
Text( Text(
"Aucun lien mort détecté", "Aucun lien mort détecté",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
Text( Text(
"Tout semble fonctionner !", "Tout semble fonctionner !",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
} }
} }
@ -198,7 +198,7 @@ private fun DeadLinkItem(
onLongClick = onLongClick onLongClick = onLongClick
), ),
colors = CardDefaults.cardColors( 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( ListViewItem(

View File

@ -34,8 +34,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.shaarit.presentation.add.ContentType import com.shaarit.presentation.add.ContentType
import com.shaarit.ui.components.* import com.shaarit.ui.components.*
import com.shaarit.ui.theme.* import com.shaarit.ui.theme.Typography
import com.shaarit.ui.theme.Purple
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class, androidx.compose.foundation.ExperimentalFoundationApi::class) @OptIn(ExperimentalMaterial3Api::class, androidx.compose.foundation.ExperimentalFoundationApi::class)
@ -107,7 +106,7 @@ fun EditLinkScreen(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background( .background(
brush = Brush.verticalGradient(colors = listOf(DeepNavy, DarkNavy)) brush = Brush.verticalGradient(colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface))
) )
) { ) {
Scaffold( Scaffold(
@ -126,13 +125,13 @@ fun EditLinkScreen(
Icon( Icon(
Icons.Default.ArrowBack, Icons.Default.ArrowBack,
contentDescription = "Retour", contentDescription = "Retour",
tint = TextPrimary tint = MaterialTheme.colorScheme.onBackground
) )
} }
}, },
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = DeepNavy.copy(alpha = 0.9f), containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
titleContentColor = TextPrimary titleContentColor = MaterialTheme.colorScheme.onBackground
) )
) )
}, },
@ -147,11 +146,11 @@ fun EditLinkScreen(
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Column(horizontalAlignment = Alignment.CenterHorizontally) { Column(horizontalAlignment = Alignment.CenterHorizontally) {
CircularProgressIndicator(color = CyanPrimary) CircularProgressIndicator(color = MaterialTheme.colorScheme.primary)
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
Text( Text(
"Chargement...", "Chargement...",
color = TextSecondary, color = MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.bodyMedium style = MaterialTheme.typography.bodyMedium
) )
} }
@ -170,7 +169,7 @@ fun EditLinkScreen(
// Content Type Selection (compact) // Content Type Selection (compact)
GlassCard( GlassCard(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
glowColor = CyanPrimary glowColor = MaterialTheme.colorScheme.primary
) { ) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -215,7 +214,7 @@ fun EditLinkScreen(
value = url, value = url,
onValueChange = { viewModel.url.value = it }, onValueChange = { viewModel.url.value = it },
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
placeholder = { Text("https://example.com", color = TextMuted) }, placeholder = { Text("https://example.com", color = MaterialTheme.colorScheme.outline) },
singleLine = true, singleLine = true,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
colors = compactTextFieldColors(), colors = compactTextFieldColors(),
@ -230,21 +229,21 @@ fun EditLinkScreen(
modifier = Modifier modifier = Modifier
.size(48.dp) // Même taille que AiMagicButton .size(48.dp) // Même taille que AiMagicButton
.background( .background(
color = SurfaceVariant.copy(alpha = 0.5f), color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f),
shape = RoundedCornerShape(12.dp) shape = RoundedCornerShape(12.dp)
) )
) { ) {
if (isExtractingMetadata) { if (isExtractingMetadata) {
CircularProgressIndicator( CircularProgressIndicator(
modifier = Modifier.size(20.dp), modifier = Modifier.size(20.dp),
color = TextSecondary, color = MaterialTheme.colorScheme.onSurfaceVariant,
strokeWidth = 2.dp strokeWidth = 2.dp
) )
} else { } else {
Icon( Icon(
Icons.Default.Refresh, Icons.Default.Refresh,
contentDescription = "Récupérer infos classique", contentDescription = "Récupérer infos classique",
tint = TextSecondary tint = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -272,7 +271,7 @@ fun EditLinkScreen(
Text( Text(
if (contentType == ContentType.NOTE) if (contentType == ContentType.NOTE)
"Titre de la note" else "Titre du lien", "Titre de la note" else "Titre du lien",
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
}, },
singleLine = true, singleLine = true,
@ -308,7 +307,7 @@ fun EditLinkScreen(
Icon( Icon(
imageVector = Icons.Default.Description, imageVector = Icons.Default.Description,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
Column { Column {
@ -317,13 +316,13 @@ fun EditLinkScreen(
"Contenu" else "Description", "Contenu" else "Description",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
if (contentType == ContentType.NOTE) { if (contentType == ContentType.NOTE) {
Text( Text(
text = "Markdown supporté", text = "Markdown supporté",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
} }
} }
@ -340,7 +339,7 @@ fun EditLinkScreen(
Icon( Icon(
Icons.Default.Edit, Icons.Default.Edit,
contentDescription = "Éditer", contentDescription = "Éditer",
tint = if (!showMarkdownPreview) CyanPrimary else TextMuted, tint = if (!showMarkdownPreview) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
} }
@ -351,7 +350,7 @@ fun EditLinkScreen(
Icon( Icon(
Icons.Default.Preview, Icons.Default.Preview,
contentDescription = "Aperçu", contentDescription = "Aperçu",
tint = if (showMarkdownPreview) CyanPrimary else TextMuted, tint = if (showMarkdownPreview) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
} }
@ -406,14 +405,14 @@ fun EditLinkScreen(
Icon( Icon(
imageVector = Icons.Default.Tag, imageVector = Icons.Default.Tag,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
Text( Text(
text = "Tags", text = "Tags",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold, 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, singleLine = true,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions( keyboardActions = KeyboardActions(
@ -480,7 +479,7 @@ fun EditLinkScreen(
Icon( Icon(
Icons.Default.Add, Icons.Default.Add,
contentDescription = "Ajouter", 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) .size(40.dp)
.background( .background(
color = if (aiTagsState is AiEnrichmentState.Loading) color = if (aiTagsState is AiEnrichmentState.Loading)
SurfaceVariant.copy(alpha = 0.5f) MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f)
else else
CyanPrimary.copy(alpha = 0.1f), MaterialTheme.colorScheme.primary.copy(alpha = 0.1f),
shape = RoundedCornerShape(12.dp) shape = RoundedCornerShape(12.dp)
) )
) { ) {
if (aiTagsState is AiEnrichmentState.Loading) { if (aiTagsState is AiEnrichmentState.Loading) {
CircularProgressIndicator( CircularProgressIndicator(
modifier = Modifier.size(20.dp), modifier = Modifier.size(20.dp),
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
strokeWidth = 2.dp strokeWidth = 2.dp
) )
} else { } else {
Icon( Icon(
Icons.Outlined.AutoAwesome, Icons.Outlined.AutoAwesome,
contentDescription = "Générer tags IA", contentDescription = "Générer tags IA",
tint = CyanPrimary tint = MaterialTheme.colorScheme.primary
) )
} }
} }
@ -524,7 +523,7 @@ fun EditLinkScreen(
Text( Text(
"Suggestions", "Suggestions",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
modifier = Modifier.padding(bottom = 8.dp) modifier = Modifier.padding(bottom = 8.dp)
) )
LazyRow( LazyRow(
@ -551,7 +550,7 @@ fun EditLinkScreen(
Text( Text(
"Populaires", "Populaires",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
modifier = Modifier.padding(bottom = 8.dp) modifier = Modifier.padding(bottom = 8.dp)
) )
LazyRow( LazyRow(
@ -589,16 +588,16 @@ fun EditLinkScreen(
Text( Text(
if (isPrivate) "Seul vous pouvez voir" else "Visible par tous", if (isPrivate) "Seul vous pouvez voir" else "Visible par tous",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
Switch( Switch(
checked = isPrivate, checked = isPrivate,
onCheckedChange = { viewModel.isPrivate.value = it }, onCheckedChange = { viewModel.isPrivate.value = it },
colors = SwitchDefaults.colors( colors = SwitchDefaults.colors(
checkedThumbColor = CyanPrimary, checkedThumbColor = MaterialTheme.colorScheme.primary,
checkedTrackColor = CyanPrimary.copy(alpha = 0.3f), checkedTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f),
uncheckedThumbColor = TextMuted, uncheckedThumbColor = MaterialTheme.colorScheme.outline,
uncheckedTrackColor = SurfaceVariant uncheckedTrackColor = MaterialTheme.colorScheme.outlineVariant
) )
) )
} }
@ -624,8 +623,8 @@ fun EditLinkScreen(
if (uiState is EditLinkUiState.Saving) { if (uiState is EditLinkUiState.Saving) {
LinearProgressIndicator( LinearProgressIndicator(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
trackColor = SurfaceVariant trackColor = MaterialTheme.colorScheme.outlineVariant
) )
} }
@ -659,8 +658,8 @@ private fun ContentTypeButton(
Surface( Surface(
onClick = onClick, onClick = onClick,
shape = RoundedCornerShape(10.dp), shape = RoundedCornerShape(10.dp),
color = if (isSelected) CyanPrimary.copy(alpha = 0.15f) else CardBackgroundElevated, color = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.15f) else MaterialTheme.colorScheme.primaryContainer,
border = if (isSelected) androidx.compose.foundation.BorderStroke(1.5.dp, CyanPrimary) else null, border = if (isSelected) androidx.compose.foundation.BorderStroke(1.5.dp, MaterialTheme.colorScheme.primary) else null,
modifier = modifier modifier = modifier
) { ) {
Row( Row(
@ -671,14 +670,14 @@ private fun ContentTypeButton(
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
tint = if (isSelected) CyanPrimary else TextSecondary, tint = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(
text = label, text = label,
style = MaterialTheme.typography.bodyMedium, 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 fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal
) )
} }
@ -705,7 +704,7 @@ private fun CompactFieldCard(
GlassCard( GlassCard(
modifier = finalModifier, modifier = finalModifier,
glowColor = CyanPrimary.copy(alpha = 0.3f) glowColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f)
) { ) {
Column { Column {
Row( Row(
@ -716,13 +715,13 @@ private fun CompactFieldCard(
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
Text( Text(
text = label, text = label,
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = TextSecondary, color = MaterialTheme.colorScheme.onSurfaceVariant,
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium
) )
} }
@ -737,13 +736,13 @@ private fun CompactFieldCard(
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun compactTextFieldColors() = OutlinedTextFieldDefaults.colors( private fun compactTextFieldColors() = OutlinedTextFieldDefaults.colors(
focusedBorderColor = CyanPrimary, focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = SurfaceVariant, unfocusedBorderColor = MaterialTheme.colorScheme.outlineVariant,
focusedLabelColor = CyanPrimary, focusedLabelColor = MaterialTheme.colorScheme.primary,
unfocusedLabelColor = TextSecondary, unfocusedLabelColor = MaterialTheme.colorScheme.onSurfaceVariant,
cursorColor = CyanPrimary, cursorColor = MaterialTheme.colorScheme.primary,
focusedContainerColor = CardBackground.copy(alpha = 0.3f), focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f),
unfocusedContainerColor = CardBackground.copy(alpha = 0.2f) unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.2f)
) )
/** /**
@ -771,8 +770,8 @@ private fun AiMagicButton(
onClick = onClick, onClick = onClick,
enabled = enabled && !isLoading, enabled = enabled && !isLoading,
shape = RoundedCornerShape(10.dp), shape = RoundedCornerShape(10.dp),
color = if (enabled) Purple.copy(alpha = if (isLoading) shimmerAlpha * 0.3f else 0.15f) else SurfaceVariant, 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, Purple) else null, border = if (enabled) androidx.compose.foundation.BorderStroke(1.5.dp, MaterialTheme.colorScheme.tertiary) else null,
modifier = modifier.size(48.dp) modifier = modifier.size(48.dp)
) { ) {
Box( Box(
@ -782,14 +781,14 @@ private fun AiMagicButton(
if (isLoading) { if (isLoading) {
CircularProgressIndicator( CircularProgressIndicator(
modifier = Modifier.size(20.dp), modifier = Modifier.size(20.dp),
color = Purple, color = MaterialTheme.colorScheme.tertiary,
strokeWidth = 2.dp strokeWidth = 2.dp
) )
} else { } else {
Icon( Icon(
imageVector = Icons.Outlined.AutoAwesome, imageVector = Icons.Outlined.AutoAwesome,
contentDescription = "Magie IA", contentDescription = "Magie IA",
tint = if (enabled) Purple else TextMuted, tint = if (enabled) MaterialTheme.colorScheme.tertiary else MaterialTheme.colorScheme.outline,
modifier = Modifier.size(22.dp) modifier = Modifier.size(22.dp)
) )
} }

View File

@ -43,7 +43,7 @@ import com.shaarit.domain.model.TagFilter
import com.shaarit.domain.model.ViewStyle import com.shaarit.domain.model.ViewStyle
import com.shaarit.ui.components.PremiumTextField import com.shaarit.ui.components.PremiumTextField
import com.shaarit.ui.components.TagChip 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.platform.LocalHapticFeedback
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.animation.* import androidx.compose.animation.*
@ -82,12 +82,12 @@ fun AccordionSection(
Text( Text(
text = title, text = title,
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
Icon( Icon(
imageVector = if (expanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore, imageVector = if (expanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
contentDescription = if (expanded) "Réduire" else "Développer", contentDescription = if (expanded) "Réduire" else "Développer",
tint = TextMuted, tint = MaterialTheme.colorScheme.outline,
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
} }
@ -136,14 +136,14 @@ fun DrawerNavigationItem(
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(24.dp) modifier = Modifier.size(24.dp)
) )
Spacer(modifier = Modifier.width(16.dp)) Spacer(modifier = Modifier.width(16.dp))
Text( Text(
text = label, text = label,
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
} }
} }
@ -158,7 +158,7 @@ fun DrawerCollectionItem(
) { ) {
Surface( Surface(
onClick = onClick, 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, shape = MaterialTheme.shapes.medium,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -178,7 +178,7 @@ fun DrawerCollectionItem(
Text( Text(
text = name, text = name,
style = MaterialTheme.typography.bodyMedium, 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, fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
@ -188,7 +188,7 @@ fun DrawerCollectionItem(
Box( Box(
modifier = Modifier modifier = Modifier
.size(8.dp) .size(8.dp)
.background(CyanPrimary, shape = MaterialTheme.shapes.small) .background(MaterialTheme.colorScheme.primary, shape = MaterialTheme.shapes.small)
) )
} }
} }
@ -203,7 +203,7 @@ fun DrawerSmartCollectionItem(
) { ) {
Surface( Surface(
onClick = onClick, 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, shape = MaterialTheme.shapes.medium,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -218,14 +218,14 @@ fun DrawerSmartCollectionItem(
Icon( Icon(
imageVector = Icons.Default.AutoAwesome, imageVector = Icons.Default.AutoAwesome,
contentDescription = null, contentDescription = null,
tint = if (isSelected) CyanPrimary else TealSecondary, tint = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
Spacer(modifier = Modifier.width(16.dp)) Spacer(modifier = Modifier.width(16.dp))
Text( Text(
text = name, text = name,
style = MaterialTheme.typography.bodyMedium, 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, fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
@ -235,7 +235,7 @@ fun DrawerSmartCollectionItem(
Box( Box(
modifier = Modifier modifier = Modifier
.size(8.dp) .size(8.dp)
.background(CyanPrimary, shape = MaterialTheme.shapes.small) .background(MaterialTheme.colorScheme.primary, shape = MaterialTheme.shapes.small)
) )
} }
} }
@ -251,16 +251,16 @@ fun DrawerTagChip(
Surface( Surface(
onClick = onClick, onClick = onClick,
shape = MaterialTheme.shapes.small, 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) { 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, } else null,
modifier = Modifier.padding(2.dp) modifier = Modifier.padding(2.dp)
) { ) {
Text( Text(
text = "#$tag", text = "#$tag",
style = MaterialTheme.typography.labelMedium, 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) modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp)
) )
} }
@ -328,8 +328,8 @@ fun FeedScreen(
drawerContent = { drawerContent = {
ModalDrawerSheet( ModalDrawerSheet(
modifier = Modifier.width(320.dp), modifier = Modifier.width(320.dp),
drawerContainerColor = DeepNavy, drawerContainerColor = MaterialTheme.colorScheme.background,
drawerContentColor = TextPrimary drawerContentColor = MaterialTheme.colorScheme.onBackground
) { ) {
// Header avec logo et titre (fixe, ne défile pas) // Header avec logo et titre (fixe, ne défile pas)
Column( Column(
@ -338,8 +338,8 @@ fun FeedScreen(
.background( .background(
brush = Brush.verticalGradient( brush = Brush.verticalGradient(
colors = listOf( colors = listOf(
CardBackgroundElevated, MaterialTheme.colorScheme.primaryContainer,
DeepNavy MaterialTheme.colorScheme.background
) )
) )
) )
@ -350,7 +350,7 @@ fun FeedScreen(
modifier = Modifier modifier = Modifier
.size(56.dp) .size(56.dp)
.background( .background(
color = CyanPrimary.copy(alpha = 0.15f), color = MaterialTheme.colorScheme.primary.copy(alpha = 0.15f),
shape = MaterialTheme.shapes.large shape = MaterialTheme.shapes.large
), ),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
@ -358,7 +358,7 @@ fun FeedScreen(
Icon( Icon(
imageVector = Icons.Default.Bookmark, imageVector = Icons.Default.Bookmark,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(28.dp) modifier = Modifier.size(28.dp)
) )
} }
@ -369,13 +369,13 @@ fun FeedScreen(
text = "ShaarIt", text = "ShaarIt",
style = MaterialTheme.typography.headlineSmall, style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
Text( Text(
text = "Vos liens, organisés", text = "Vos liens, organisés",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
@ -453,7 +453,7 @@ fun FeedScreen(
} }
Divider( Divider(
color = TextMuted.copy(alpha = 0.2f), color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f),
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
) )
@ -584,7 +584,7 @@ fun FeedScreen(
} }
Divider( Divider(
color = TextMuted.copy(alpha = 0.2f), color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f),
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
) )
@ -603,7 +603,7 @@ fun FeedScreen(
Text( Text(
"Voir tout", "Voir tout",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = CyanPrimary color = MaterialTheme.colorScheme.primary
) )
} }
} }
@ -650,7 +650,7 @@ fun FeedScreen(
} }
Divider( Divider(
color = TextMuted.copy(alpha = 0.2f), color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f),
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
) )
@ -669,7 +669,7 @@ fun FeedScreen(
Text( Text(
"Voir tout", "Voir tout",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = CyanPrimary color = MaterialTheme.colorScheme.primary
) )
} }
} }
@ -702,7 +702,7 @@ fun FeedScreen(
Text( Text(
text = "© 2026 ShaarIt", text = "© 2026 ShaarIt",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted.copy(alpha = 0.6f), color = MaterialTheme.colorScheme.outline.copy(alpha = 0.6f),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(16.dp), .padding(16.dp),
@ -716,7 +716,7 @@ fun FeedScreen(
.fillMaxSize() .fillMaxSize()
.background( .background(
brush = Brush.verticalGradient( brush = Brush.verticalGradient(
colors = listOf(DeepNavy, DarkNavy) colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface)
) )
) )
) { ) {
@ -729,7 +729,7 @@ fun FeedScreen(
"ShaarIt", "ShaarIt",
style = MaterialTheme.typography.headlineSmall, style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
}, },
navigationIcon = { navigationIcon = {
@ -743,7 +743,7 @@ fun FeedScreen(
Icon( Icon(
imageVector = Icons.Default.Close, imageVector = Icons.Default.Close,
contentDescription = "Exit selection", contentDescription = "Exit selection",
tint = CyanPrimary tint = MaterialTheme.colorScheme.primary
) )
} }
} else { } else {
@ -751,7 +751,7 @@ fun FeedScreen(
Icon( Icon(
imageVector = Icons.Default.Menu, imageVector = Icons.Default.Menu,
contentDescription = "Menu", contentDescription = "Menu",
tint = CyanPrimary tint = MaterialTheme.colorScheme.primary
) )
} }
} }
@ -760,7 +760,7 @@ fun FeedScreen(
if (selectionMode) { if (selectionMode) {
Text( Text(
text = selectedIds.size.toString(), text = selectedIds.size.toString(),
color = TextSecondary, color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(horizontal = 8.dp) modifier = Modifier.padding(horizontal = 8.dp)
) )
IconButton( IconButton(
@ -770,7 +770,7 @@ fun FeedScreen(
Icon( Icon(
imageVector = Icons.Default.Folder, imageVector = Icons.Default.Folder,
contentDescription = "Add to collection", contentDescription = "Add to collection",
tint = if (selectedIds.isNotEmpty()) CyanPrimary else TextMuted tint = if (selectedIds.isNotEmpty()) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline
) )
} }
IconButton( IconButton(
@ -782,7 +782,7 @@ fun FeedScreen(
Icon( Icon(
imageVector = Icons.Default.Close, imageVector = Icons.Default.Close,
contentDescription = "Cancel selection", contentDescription = "Cancel selection",
tint = TextSecondary tint = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
return@TopAppBar return@TopAppBar
@ -797,7 +797,7 @@ fun FeedScreen(
Icon( Icon(
imageVector = Icons.Default.Refresh, imageVector = Icons.Default.Refresh,
contentDescription = "Refresh", contentDescription = "Refresh",
tint = CyanPrimary tint = MaterialTheme.colorScheme.primary
) )
} }
@ -811,14 +811,14 @@ fun FeedScreen(
ViewStyle.COMPACT -> Icons.Default.ViewList ViewStyle.COMPACT -> Icons.Default.ViewList
}, },
contentDescription = "View style", contentDescription = "View style",
tint = CyanPrimary tint = MaterialTheme.colorScheme.primary
) )
} }
DropdownMenu( DropdownMenu(
expanded = showViewStyleMenu, expanded = showViewStyleMenu,
onDismissRequest = { showViewStyleMenu = false }, onDismissRequest = { showViewStyleMenu = false },
modifier = Modifier.background(CardBackground) modifier = Modifier.background(MaterialTheme.colorScheme.surfaceVariant)
) { ) {
DropdownMenuItem( DropdownMenuItem(
text = { text = {
@ -829,11 +829,11 @@ fun FeedScreen(
Icon( Icon(
Icons.Default.ViewStream, Icons.Default.ViewStream,
contentDescription = null, contentDescription = null,
tint = if (viewStyle == ViewStyle.LIST) CyanPrimary else TextSecondary tint = if (viewStyle == ViewStyle.LIST) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
) )
Text( Text(
"List View", "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( Icon(
Icons.Default.ViewModule, Icons.Default.ViewModule,
contentDescription = null, contentDescription = null,
tint = if (viewStyle == ViewStyle.GRID) CyanPrimary else TextSecondary tint = if (viewStyle == ViewStyle.GRID) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
) )
Text( Text(
"Grid View", "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( Icon(
Icons.Default.ViewList, Icons.Default.ViewList,
contentDescription = null, contentDescription = null,
tint = if (viewStyle == ViewStyle.COMPACT) CyanPrimary else TextSecondary tint = if (viewStyle == ViewStyle.COMPACT) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
) )
Text( Text(
"Compact View", "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( Icon(
imageVector = Icons.Default.FilterList, imageVector = Icons.Default.FilterList,
contentDescription = "Filters", contentDescription = "Filters",
tint = CyanPrimary tint = MaterialTheme.colorScheme.primary
) )
} }
DropdownMenu( DropdownMenu(
expanded = showSortOrderMenu, expanded = showSortOrderMenu,
onDismissRequest = { showSortOrderMenu = false }, onDismissRequest = { showSortOrderMenu = false },
modifier = Modifier.background(CardBackground) modifier = Modifier.background(MaterialTheme.colorScheme.surfaceVariant)
) { ) {
// Sort Direction Section // Sort Direction Section
Text( Text(
text = "TRI", text = "TRI",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
) )
DropdownMenuItem( DropdownMenuItem(
@ -920,11 +920,11 @@ fun FeedScreen(
Icon( Icon(
Icons.Default.ArrowDownward, Icons.Default.ArrowDownward,
contentDescription = null, 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( Text(
"Plus récent d'abord", "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( Icon(
Icons.Default.ArrowUpward, Icons.Default.ArrowUpward,
contentDescription = null, 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( Text(
"Plus ancien d'abord", "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 // Time Filter Section
Text( Text(
text = "PÉRIODE", text = "PÉRIODE",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
) )
DropdownMenuItem( DropdownMenuItem(
@ -972,11 +972,11 @@ fun FeedScreen(
Icon( Icon(
Icons.Default.AllInclusive, Icons.Default.AllInclusive,
contentDescription = null, 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( Text(
"Tous les bookmarks", "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( Icon(
Icons.Default.Today, Icons.Default.Today,
contentDescription = null, 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( Text(
"Aujourd'hui", "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( Icon(
Icons.Default.DateRange, Icons.Default.DateRange,
contentDescription = null, 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( Text(
"Cette semaine", "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( Icon(
Icons.Default.CalendarMonth, Icons.Default.CalendarMonth,
contentDescription = null, 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( Text(
"Ce mois-ci", "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 // Visibility Filter Section
Text( Text(
text = "VISIBILITÉ", text = "VISIBILITÉ",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
) )
DropdownMenuItem( DropdownMenuItem(
@ -1066,11 +1066,11 @@ fun FeedScreen(
Icon( Icon(
Icons.Default.Visibility, Icons.Default.Visibility,
contentDescription = null, 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( Text(
"Publics et Privés", "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( Icon(
Icons.Default.Public, Icons.Default.Public,
contentDescription = null, 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( Text(
"Publics uniquement", "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( Icon(
Icons.Default.Lock, Icons.Default.Lock,
contentDescription = null, 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( Text(
"Privés uniquement", "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 // Tag Filter Section
Text( Text(
text = "TAGS", text = "TAGS",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
) )
DropdownMenuItem( DropdownMenuItem(
@ -1139,11 +1139,11 @@ fun FeedScreen(
Icon( Icon(
Icons.Default.Label, Icons.Default.Label,
contentDescription = null, 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( Text(
"Tous les tags", "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( Icon(
Icons.Default.LabelOff, Icons.Default.LabelOff,
contentDescription = null, 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( Text(
"Sans tags", "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 // Reset button
DropdownMenuItem( DropdownMenuItem(
@ -1185,11 +1185,11 @@ fun FeedScreen(
Icon( Icon(
Icons.Default.Refresh, Icons.Default.Refresh,
contentDescription = null, contentDescription = null,
tint = TextSecondary tint = MaterialTheme.colorScheme.onSurfaceVariant
) )
Text( Text(
"Réinitialiser les filtres", "Réinitialiser les filtres",
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
} }
}, },
@ -1202,8 +1202,8 @@ fun FeedScreen(
} }
}, },
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = DeepNavy.copy(alpha = 0.9f), containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
titleContentColor = TextPrimary titleContentColor = MaterialTheme.colorScheme.onBackground
) )
) )
@ -1220,7 +1220,7 @@ fun FeedScreen(
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background(DarkNavy) .background(MaterialTheme.colorScheme.surface)
.padding(horizontal = 16.dp, vertical = 8.dp), .padding(horizontal = 16.dp, vertical = 8.dp),
verticalAlignment = Alignment.Top, verticalAlignment = Alignment.Top,
horizontalArrangement = Arrangement.spacedBy(8.dp) horizontalArrangement = Arrangement.spacedBy(8.dp)
@ -1228,7 +1228,7 @@ fun FeedScreen(
Text( Text(
"Filtering by:", "Filtering by:",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextSecondary, color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(top = 6.dp) modifier = Modifier.padding(top = 6.dp)
) )
@ -1240,8 +1240,8 @@ fun FeedScreen(
onClick = { viewModel.clearCollectionFilter() }, onClick = { viewModel.clearCollectionFilter() },
label = { Text(collectionName) }, label = { Text(collectionName) },
colors = AssistChipDefaults.assistChipColors( colors = AssistChipDefaults.assistChipColors(
containerColor = CardBackground, containerColor = MaterialTheme.colorScheme.surfaceVariant,
labelColor = CyanPrimary labelColor = MaterialTheme.colorScheme.primary
) )
) )
} }
@ -1282,7 +1282,7 @@ fun FeedScreen(
Icon( Icon(
Icons.Default.Close, Icons.Default.Close,
contentDescription = "Clear filter", contentDescription = "Clear filter",
tint = TextMuted, tint = MaterialTheme.colorScheme.outline,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
} }
@ -1300,7 +1300,7 @@ fun FeedScreen(
Icon( Icon(
Icons.Default.Search, Icons.Default.Search,
contentDescription = null, contentDescription = null,
tint = TextMuted tint = MaterialTheme.colorScheme.outline
) )
}, },
trailingIcon = { trailingIcon = {
@ -1311,7 +1311,7 @@ fun FeedScreen(
Icon( Icon(
Icons.Default.Close, Icons.Default.Close,
contentDescription = "Clear", contentDescription = "Clear",
tint = TextMuted tint = MaterialTheme.colorScheme.outline
) )
} }
} }
@ -1324,8 +1324,8 @@ fun FeedScreen(
floatingActionButton = { floatingActionButton = {
FloatingActionButton( FloatingActionButton(
onClick = onNavigateToAdd, onClick = onNavigateToAdd,
containerColor = CyanPrimary, containerColor = MaterialTheme.colorScheme.primary,
contentColor = DeepNavy contentColor = MaterialTheme.colorScheme.background
) { Icon(Icons.Default.Add, contentDescription = "Add Link") } ) { Icon(Icons.Default.Add, contentDescription = "Add Link") }
}, },
containerColor = Color.Transparent containerColor = Color.Transparent
@ -1350,7 +1350,7 @@ fun FeedScreen(
Text( Text(
"Failed to load links", "Failed to load links",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
color = ErrorRed color = MaterialTheme.colorScheme.error
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
IconButton(onClick = { IconButton(onClick = {
@ -1360,7 +1360,7 @@ fun FeedScreen(
Icon( Icon(
Icons.Default.Refresh, Icons.Default.Refresh,
contentDescription = "Refresh", contentDescription = "Refresh",
tint = CyanPrimary tint = MaterialTheme.colorScheme.primary
) )
} }
} }
@ -1377,7 +1377,7 @@ fun FeedScreen(
"No links found" "No links found"
else "No links yet", else "No links yet",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
@ -1385,7 +1385,7 @@ fun FeedScreen(
"Try a different search" "Try a different search"
else "Add your first link!", else "Add your first link!",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
} }
} }
@ -1447,7 +1447,7 @@ fun FeedScreen(
) { ) {
CircularProgressIndicator( CircularProgressIndicator(
modifier = Modifier.padding(16.dp), modifier = Modifier.padding(16.dp),
color = CyanPrimary color = MaterialTheme.colorScheme.primary
) )
} }
} }
@ -1507,7 +1507,7 @@ fun FeedScreen(
) { ) {
CircularProgressIndicator( CircularProgressIndicator(
modifier = Modifier.padding(16.dp), modifier = Modifier.padding(16.dp),
color = CyanPrimary color = MaterialTheme.colorScheme.primary
) )
} }
} }
@ -1568,7 +1568,7 @@ fun FeedScreen(
) { ) {
CircularProgressIndicator( CircularProgressIndicator(
modifier = Modifier.padding(16.dp), modifier = Modifier.padding(16.dp),
color = CyanPrimary color = MaterialTheme.colorScheme.primary
) )
} }
} }
@ -1584,8 +1584,8 @@ fun FeedScreen(
refreshing = pagingItems.loadState.refresh is LoadState.Loading, refreshing = pagingItems.loadState.refresh is LoadState.Loading,
state = pullRefreshState, state = pullRefreshState,
modifier = Modifier.align(Alignment.TopCenter), modifier = Modifier.align(Alignment.TopCenter),
backgroundColor = DarkNavy, backgroundColor = MaterialTheme.colorScheme.surface,
contentColor = CyanPrimary contentColor = MaterialTheme.colorScheme.primary
) )
} }
} }

View File

@ -37,7 +37,7 @@ import com.shaarit.domain.model.HealthStatus
import com.shaarit.domain.model.ShaarliLink import com.shaarit.domain.model.ShaarliLink
import com.shaarit.ui.components.GlassCard import com.shaarit.ui.components.GlassCard
import com.shaarit.ui.components.TagChip import com.shaarit.ui.components.TagChip
import com.shaarit.ui.theme.* import com.shaarit.ui.theme.Typography
import dev.jeziellago.compose.markdowntext.MarkdownText import dev.jeziellago.compose.markdowntext.MarkdownText
import coil.compose.AsyncImage import coil.compose.AsyncImage
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
@ -78,7 +78,7 @@ fun ListViewItem(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
onClick = { (onItemClick ?: { onLinkClick(link.url) }).invoke() }, onClick = { (onItemClick ?: { onLinkClick(link.url) }).invoke() },
onLongClick = onItemLongClick, onLongClick = onItemLongClick,
glowColor = if (isSelected) CyanPrimary else CyanPrimary glowColor = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primary
) { ) {
Column { Column {
Row( Row(
@ -103,7 +103,7 @@ fun ListViewItem(
text = link.displayTitle, text = link.displayTitle,
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -118,9 +118,9 @@ fun ListViewItem(
text = link.url, text = link.url,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = when (link.healthStatus) { color = when (link.healthStatus) {
HealthStatus.DEAD -> ErrorRed HealthStatus.DEAD -> MaterialTheme.colorScheme.error
HealthStatus.OK -> TealSecondary HealthStatus.OK -> MaterialTheme.colorScheme.secondary
else -> TextMuted else -> MaterialTheme.colorScheme.outline
}, },
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
@ -143,7 +143,7 @@ fun ListViewItem(
Icon( Icon(
imageVector = Icons.Default.PushPin, imageVector = Icons.Default.PushPin,
contentDescription = if (link.isPinned) "Désépingler" else "Épingler", 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) modifier = Modifier.size(18.dp)
) )
} }
@ -151,7 +151,7 @@ fun ListViewItem(
Icon( Icon(
imageVector = Icons.Default.Visibility, imageVector = Icons.Default.Visibility,
contentDescription = "View Details", contentDescription = "View Details",
tint = CyanPrimary.copy(alpha = 0.7f), tint = MaterialTheme.colorScheme.primary.copy(alpha = 0.7f),
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
} }
@ -159,7 +159,7 @@ fun ListViewItem(
Icon( Icon(
imageVector = Icons.Default.Edit, imageVector = Icons.Default.Edit,
contentDescription = "Edit", contentDescription = "Edit",
tint = TealSecondary.copy(alpha = 0.7f), tint = MaterialTheme.colorScheme.secondary.copy(alpha = 0.7f),
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
} }
@ -167,7 +167,7 @@ fun ListViewItem(
Icon( Icon(
imageVector = Icons.Default.Delete, imageVector = Icons.Default.Delete,
contentDescription = "Delete", contentDescription = "Delete",
tint = ErrorRed.copy(alpha = 0.7f), tint = MaterialTheme.colorScheme.error.copy(alpha = 0.7f),
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
} }
@ -178,7 +178,7 @@ fun ListViewItem(
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
MarkdownText( MarkdownText(
markdown = link.description, markdown = link.description,
style = MaterialTheme.typography.bodyMedium.copy(color = TextSecondary), style = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onSurfaceVariant),
maxLines = 5, maxLines = 5,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
@ -203,7 +203,7 @@ fun ListViewItem(
Text( Text(
text = link.date, text = link.date,
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
if (link.isPrivate) { if (link.isPrivate) {
@ -214,13 +214,13 @@ fun ListViewItem(
Icon( Icon(
Icons.Default.Lock, Icons.Default.Lock,
contentDescription = "Private", contentDescription = "Private",
tint = TextMuted, tint = MaterialTheme.colorScheme.outline,
modifier = Modifier.size(12.dp) modifier = Modifier.size(12.dp)
) )
Text( Text(
text = "Private", text = "Private",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
} }
} }
@ -264,7 +264,7 @@ fun GridViewItem(
.heightIn(min = 220.dp), .heightIn(min = 220.dp),
onClick = { (onItemClick ?: { onLinkClick(link.url) }).invoke() }, onClick = { (onItemClick ?: { onLinkClick(link.url) }).invoke() },
onLongClick = onItemLongClick, onLongClick = onItemLongClick,
glowColor = if (isSelected) CyanPrimary else CyanPrimary glowColor = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primary
) { ) {
Column( Column(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
@ -301,9 +301,9 @@ fun GridViewItem(
style = MaterialTheme.typography.titleSmall, style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = when (link.healthStatus) { color = when (link.healthStatus) {
HealthStatus.DEAD -> ErrorRed HealthStatus.DEAD -> MaterialTheme.colorScheme.error
HealthStatus.OK -> CyanPrimary HealthStatus.OK -> MaterialTheme.colorScheme.primary
else -> CyanPrimary.copy(alpha = 0.7f) else -> MaterialTheme.colorScheme.primary.copy(alpha = 0.7f)
}, },
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
@ -314,7 +314,7 @@ fun GridViewItem(
Icon( Icon(
imageVector = Icons.Default.PushPin, imageVector = Icons.Default.PushPin,
contentDescription = "Épinglé", contentDescription = "Épinglé",
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
} }
@ -326,7 +326,7 @@ fun GridViewItem(
if (link.description.isNotBlank()) { if (link.description.isNotBlank()) {
MarkdownText( MarkdownText(
markdown = link.description, markdown = link.description,
style = MaterialTheme.typography.bodySmall.copy(color = TextSecondary), style = MaterialTheme.typography.bodySmall.copy(color = MaterialTheme.colorScheme.onSurfaceVariant),
maxLines = 3, maxLines = 3,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
@ -344,7 +344,7 @@ fun GridViewItem(
Text( Text(
text = "#$tag", text = "#$tag",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TealSecondary, color = MaterialTheme.colorScheme.secondary,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -353,7 +353,7 @@ fun GridViewItem(
Text( Text(
text = "+${link.tags.size - 2}", text = "+${link.tags.size - 2}",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
} }
} }
@ -379,14 +379,14 @@ fun GridViewItem(
Icon( Icon(
Icons.Default.Lock, Icons.Default.Lock,
contentDescription = "Private", contentDescription = "Private",
tint = TextMuted, tint = MaterialTheme.colorScheme.outline,
modifier = Modifier.size(12.dp) modifier = Modifier.size(12.dp)
) )
} }
Text( Text(
text = link.date.take(10), text = link.date.take(10),
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
} }
@ -399,7 +399,7 @@ fun GridViewItem(
Icon( Icon(
imageVector = Icons.Default.PushPin, imageVector = Icons.Default.PushPin,
contentDescription = if (link.isPinned) "Désépingler" else "Épingler", 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) modifier = Modifier.size(14.dp)
) )
} }
@ -410,7 +410,7 @@ fun GridViewItem(
Icon( Icon(
imageVector = Icons.Default.Visibility, imageVector = Icons.Default.Visibility,
contentDescription = "View Details", contentDescription = "View Details",
tint = CyanPrimary.copy(alpha = 0.7f), tint = MaterialTheme.colorScheme.primary.copy(alpha = 0.7f),
modifier = Modifier.size(14.dp) modifier = Modifier.size(14.dp)
) )
} }
@ -421,7 +421,7 @@ fun GridViewItem(
Icon( Icon(
imageVector = Icons.Default.Edit, imageVector = Icons.Default.Edit,
contentDescription = "Edit", contentDescription = "Edit",
tint = TealSecondary.copy(alpha = 0.7f), tint = MaterialTheme.colorScheme.secondary.copy(alpha = 0.7f),
modifier = Modifier.size(14.dp) modifier = Modifier.size(14.dp)
) )
} }
@ -432,7 +432,7 @@ fun GridViewItem(
Icon( Icon(
imageVector = Icons.Default.Delete, imageVector = Icons.Default.Delete,
contentDescription = "Delete", contentDescription = "Delete",
tint = ErrorRed.copy(alpha = 0.7f), tint = MaterialTheme.colorScheme.error.copy(alpha = 0.7f),
modifier = Modifier.size(14.dp) modifier = Modifier.size(14.dp)
) )
} }
@ -481,7 +481,7 @@ fun CompactViewItem(
onClick = { (onItemClick ?: { onLinkClick(link.url) }).invoke() }, onClick = { (onItemClick ?: { onLinkClick(link.url) }).invoke() },
onLongClick = onItemLongClick onLongClick = onItemLongClick
), ),
color = CardBackground.copy(alpha = 0.7f) color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.7f)
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
@ -506,7 +506,7 @@ fun CompactViewItem(
Icon( Icon(
imageVector = Icons.Default.PushPin, imageVector = Icons.Default.PushPin,
contentDescription = "Épinglé", contentDescription = "Épinglé",
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(14.dp) modifier = Modifier.size(14.dp)
) )
} }
@ -515,7 +515,7 @@ fun CompactViewItem(
Icon( Icon(
Icons.Default.Lock, Icons.Default.Lock,
contentDescription = "Private", contentDescription = "Private",
tint = TextMuted, tint = MaterialTheme.colorScheme.outline,
modifier = Modifier.size(14.dp) modifier = Modifier.size(14.dp)
) )
} }
@ -531,9 +531,9 @@ fun CompactViewItem(
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
color = when (link.healthStatus) { color = when (link.healthStatus) {
HealthStatus.DEAD -> ErrorRed HealthStatus.DEAD -> MaterialTheme.colorScheme.error
HealthStatus.OK -> CyanPrimary HealthStatus.OK -> MaterialTheme.colorScheme.primary
else -> CyanPrimary.copy(alpha = 0.7f) else -> MaterialTheme.colorScheme.primary.copy(alpha = 0.7f)
}, },
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
@ -547,14 +547,14 @@ fun CompactViewItem(
Text( Text(
text = link.date.take(10), text = link.date.take(10),
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
if (link.tags.isNotEmpty()) { if (link.tags.isNotEmpty()) {
Text( Text(
text = link.tags.take(2).joinToString { "#$it" }, text = link.tags.take(2).joinToString { "#$it" },
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TealSecondary, color = MaterialTheme.colorScheme.secondary,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -571,7 +571,7 @@ fun CompactViewItem(
Icon( Icon(
imageVector = Icons.Default.PushPin, imageVector = Icons.Default.PushPin,
contentDescription = if (link.isPinned) "Désépingler" else "Épingler", 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) modifier = Modifier.size(16.dp)
) )
} }
@ -579,7 +579,7 @@ fun CompactViewItem(
Icon( Icon(
imageVector = Icons.Default.Visibility, imageVector = Icons.Default.Visibility,
contentDescription = "View Details", contentDescription = "View Details",
tint = CyanPrimary.copy(alpha = 0.7f), tint = MaterialTheme.colorScheme.primary.copy(alpha = 0.7f),
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
} }
@ -587,7 +587,7 @@ fun CompactViewItem(
Icon( Icon(
imageVector = Icons.Default.Edit, imageVector = Icons.Default.Edit,
contentDescription = "Edit", contentDescription = "Edit",
tint = TealSecondary.copy(alpha = 0.7f), tint = MaterialTheme.colorScheme.secondary.copy(alpha = 0.7f),
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
} }
@ -595,7 +595,7 @@ fun CompactViewItem(
Icon( Icon(
imageVector = Icons.Default.Delete, imageVector = Icons.Default.Delete,
contentDescription = "Delete", contentDescription = "Delete",
tint = ErrorRed.copy(alpha = 0.7f), tint = MaterialTheme.colorScheme.error.copy(alpha = 0.7f),
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
} }
@ -615,14 +615,14 @@ fun DeleteConfirmationDialog(
) { ) {
AlertDialog( AlertDialog(
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
title = { Text("Delete Link", fontWeight = FontWeight.Bold, color = TextPrimary) }, title = { Text("Delete Link", fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.onBackground) },
text = { text = {
Column { 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)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
linkTitle, linkTitle,
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
@ -631,17 +631,17 @@ fun DeleteConfirmationDialog(
}, },
confirmButton = { confirmButton = {
TextButton(onClick = onConfirm) { TextButton(onClick = onConfirm) {
Text("Delete", color = ErrorRed) Text("Delete", color = MaterialTheme.colorScheme.error)
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismiss) { TextButton(onClick = onDismiss) {
Text("Cancel", color = TextMuted) Text("Cancel", color = MaterialTheme.colorScheme.outline)
} }
}, },
containerColor = CardBackground, containerColor = MaterialTheme.colorScheme.surfaceVariant,
titleContentColor = TextPrimary, titleContentColor = MaterialTheme.colorScheme.onBackground,
textContentColor = TextSecondary textContentColor = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
@ -691,7 +691,7 @@ fun LinkDetailsView(
text = link.displayTitle, text = link.displayTitle,
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
modifier = Modifier.weight(1f) modifier = Modifier.weight(1f)
) )
IconButton( IconButton(
@ -703,7 +703,7 @@ fun LinkDetailsView(
Icon( Icon(
imageVector = Icons.Default.Close, imageVector = Icons.Default.Close,
contentDescription = "Close", contentDescription = "Close",
tint = TextSecondary tint = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -734,7 +734,7 @@ fun LinkDetailsView(
Text( Text(
text = link.url, text = link.url,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TealSecondary, color = MaterialTheme.colorScheme.secondary,
modifier = Modifier modifier = Modifier
.clickable { onLinkClick(link.url) } .clickable { onLinkClick(link.url) }
.padding(vertical = 4.dp) .padding(vertical = 4.dp)
@ -767,7 +767,7 @@ fun LinkDetailsView(
Text( Text(
text = link.date, text = link.date,
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
if (link.isPrivate) { if (link.isPrivate) {
Row( Row(
@ -777,34 +777,34 @@ fun LinkDetailsView(
Icon( Icon(
Icons.Default.Lock, Icons.Default.Lock,
contentDescription = "Private", contentDescription = "Private",
tint = TextMuted, tint = MaterialTheme.colorScheme.outline,
modifier = Modifier.size(14.dp) modifier = Modifier.size(14.dp)
) )
Text( Text(
text = "Private", text = "Private",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted color = MaterialTheme.colorScheme.outline
) )
} }
} }
} }
Spacer(modifier = Modifier.height(24.dp)) 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)) Spacer(modifier = Modifier.height(24.dp))
// Description // Description
if (link.description.isNotBlank()) { if (link.description.isNotBlank()) {
MarkdownText( MarkdownText(
markdown = link.description, markdown = link.description,
style = MaterialTheme.typography.bodyMedium.copy(color = TextPrimary), style = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onBackground),
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
} else { } else {
Text( Text(
text = "No description", text = "No description",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
fontStyle = androidx.compose.ui.text.font.FontStyle.Italic fontStyle = androidx.compose.ui.text.font.FontStyle.Italic
) )
} }
@ -834,7 +834,7 @@ fun HealthStatusIcon(
Icon( Icon(
imageVector = Icons.Default.HelpOutline, imageVector = Icons.Default.HelpOutline,
contentDescription = "Non testé", contentDescription = "Non testé",
tint = TextMuted, tint = MaterialTheme.colorScheme.outline,
modifier = modifier modifier = modifier
) )
} }
@ -842,7 +842,7 @@ fun HealthStatusIcon(
Icon( Icon(
imageVector = Icons.Default.CheckCircle, imageVector = Icons.Default.CheckCircle,
contentDescription = "Lien fonctionnel", contentDescription = "Lien fonctionnel",
tint = SuccessGreen, tint = Color(0xFF10B981),
modifier = modifier modifier = modifier
) )
} }
@ -858,7 +858,7 @@ fun HealthStatusIcon(
Icon( Icon(
imageVector = Icons.Default.BrokenImage, imageVector = Icons.Default.BrokenImage,
contentDescription = "Lien mort", contentDescription = "Lien mort",
tint = ErrorRed, tint = MaterialTheme.colorScheme.error,
modifier = modifier modifier = modifier
) )
} }

View File

@ -17,7 +17,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.shaarit.ui.theme.* import com.shaarit.ui.theme.Typography
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -30,7 +30,7 @@ fun HelpScreen(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background( .background(
brush = Brush.verticalGradient(colors = listOf(DeepNavy, DarkNavy)) brush = Brush.verticalGradient(colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface))
) )
) { ) {
Scaffold( Scaffold(
@ -48,13 +48,13 @@ fun HelpScreen(
Icon( Icon(
Icons.Default.ArrowBack, Icons.Default.ArrowBack,
contentDescription = "Retour", contentDescription = "Retour",
tint = TextPrimary tint = MaterialTheme.colorScheme.onBackground
) )
} }
}, },
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = DeepNavy.copy(alpha = 0.9f), containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
titleContentColor = TextPrimary titleContentColor = MaterialTheme.colorScheme.onBackground
) )
) )
}, },
@ -600,7 +600,7 @@ fun HelpScreen(
Text( Text(
text = "ShaarIt v1.0 • © 2026", text = "ShaarIt v1.0 • © 2026",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted.copy(alpha = 0.6f), color = MaterialTheme.colorScheme.outline.copy(alpha = 0.6f),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
@ -618,9 +618,9 @@ private fun HelpHeader() {
Card( Card(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors( 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( Row(
modifier = Modifier modifier = Modifier
@ -632,7 +632,7 @@ private fun HelpHeader() {
modifier = Modifier modifier = Modifier
.size(48.dp) .size(48.dp)
.background( .background(
color = CyanPrimary.copy(alpha = 0.2f), color = MaterialTheme.colorScheme.primary.copy(alpha = 0.2f),
shape = MaterialTheme.shapes.medium shape = MaterialTheme.shapes.medium
), ),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
@ -640,7 +640,7 @@ private fun HelpHeader() {
Icon( Icon(
imageVector = Icons.Default.MenuBook, imageVector = Icons.Default.MenuBook,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(28.dp) modifier = Modifier.size(28.dp)
) )
} }
@ -650,12 +650,12 @@ private fun HelpHeader() {
text = "Guide Complet", text = "Guide Complet",
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
Text( Text(
text = "Tout ce qu'il faut savoir pour maîtriser ShaarIt", text = "Tout ce qu'il faut savoir pour maîtriser ShaarIt",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -673,7 +673,7 @@ private fun HelpSection(
Card( Card(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors( colors = CardDefaults.cardColors(
containerColor = CardBackground containerColor = MaterialTheme.colorScheme.surfaceVariant
) )
) { ) {
Column { Column {
@ -691,7 +691,7 @@ private fun HelpSection(
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
tint = CyanPrimary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(24.dp) modifier = Modifier.size(24.dp)
) )
Spacer(modifier = Modifier.width(12.dp)) Spacer(modifier = Modifier.width(12.dp))
@ -699,13 +699,13 @@ private fun HelpSection(
text = title, text = title,
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = TextPrimary, color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.weight(1f) modifier = Modifier.weight(1f)
) )
Icon( Icon(
imageVector = if (isExpanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore, imageVector = if (isExpanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
contentDescription = if (isExpanded) "Réduire" else "Développer", contentDescription = if (isExpanded) "Réduire" else "Développer",
tint = TextMuted tint = MaterialTheme.colorScheme.outline
) )
} }
} }
@ -720,7 +720,7 @@ private fun HelpSection(
.fillMaxWidth() .fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp) .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)) Spacer(modifier = Modifier.height(12.dp))
content() content()
} }
@ -744,7 +744,7 @@ private fun HelpSubsection(
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
tint = TealSecondary, tint = MaterialTheme.colorScheme.secondary,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
Spacer(modifier = Modifier.width(12.dp)) Spacer(modifier = Modifier.width(12.dp))
@ -753,13 +753,13 @@ private fun HelpSubsection(
text = title, text = title,
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
Spacer(modifier = Modifier.height(2.dp)) Spacer(modifier = Modifier.height(2.dp))
Text( Text(
text = description, text = description,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -770,7 +770,7 @@ private fun HelpText(text: String) {
Text( Text(
text = text, text = text,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
@ -780,7 +780,7 @@ private fun HelpSubtitle(text: String) {
text = text, text = text,
style = MaterialTheme.typography.titleSmall, style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = CyanLight color = MaterialTheme.colorScheme.tertiary
) )
} }
@ -792,14 +792,14 @@ private fun HelpFeatureList(items: List<String>) {
Icon( Icon(
imageVector = Icons.Default.CheckCircle, imageVector = Icons.Default.CheckCircle,
contentDescription = null, contentDescription = null,
tint = SuccessGreen, tint = Color(0xFF10B981),
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(
text = item, text = item,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
} }
} }
@ -814,13 +814,13 @@ private fun HelpBulletList(items: List<String>) {
Text( Text(
text = "", text = "",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
modifier = Modifier.width(16.dp) modifier = Modifier.width(16.dp)
) )
Text( Text(
text = item, text = item,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -836,7 +836,7 @@ private fun HelpNumberedList(items: List<Pair<String, String>>) {
modifier = Modifier modifier = Modifier
.size(24.dp) .size(24.dp)
.background( .background(
color = CyanPrimary.copy(alpha = 0.2f), color = MaterialTheme.colorScheme.primary.copy(alpha = 0.2f),
shape = MaterialTheme.shapes.small shape = MaterialTheme.shapes.small
), ),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
@ -845,7 +845,7 @@ private fun HelpNumberedList(items: List<Pair<String, String>>) {
text = "${index + 1}", text = "${index + 1}",
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = CyanPrimary color = MaterialTheme.colorScheme.primary
) )
} }
Spacer(modifier = Modifier.width(12.dp)) Spacer(modifier = Modifier.width(12.dp))
@ -854,14 +854,14 @@ private fun HelpNumberedList(items: List<Pair<String, String>>) {
text = title, text = title,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
if (description.isNotBlank()) { if (description.isNotBlank()) {
Spacer(modifier = Modifier.height(2.dp)) Spacer(modifier = Modifier.height(2.dp))
Text( Text(
text = description, text = description,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -878,7 +878,7 @@ private fun HelpInfoCard(
Card( Card(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors( colors = CardDefaults.cardColors(
containerColor = CardBackgroundElevated containerColor = MaterialTheme.colorScheme.primaryContainer
) )
) { ) {
Column( Column(
@ -888,7 +888,7 @@ private fun HelpInfoCard(
Icon( Icon(
imageVector = Icons.Default.Info, imageVector = Icons.Default.Info,
contentDescription = null, contentDescription = null,
tint = TealSecondary, tint = MaterialTheme.colorScheme.secondary,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
@ -896,14 +896,14 @@ private fun HelpInfoCard(
text = title, text = title,
style = MaterialTheme.typography.labelLarge, style = MaterialTheme.typography.labelLarge,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = TealSecondary color = MaterialTheme.colorScheme.secondary
) )
} }
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
text = content, text = content,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -915,7 +915,7 @@ private fun HelpTip(text: String) {
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background( .background(
color = SuccessGreen.copy(alpha = 0.1f), color = Color(0xFF10B981).copy(alpha = 0.1f),
shape = MaterialTheme.shapes.small shape = MaterialTheme.shapes.small
) )
.padding(12.dp), .padding(12.dp),
@ -924,14 +924,14 @@ private fun HelpTip(text: String) {
Icon( Icon(
imageVector = Icons.Default.Lightbulb, imageVector = Icons.Default.Lightbulb,
contentDescription = null, contentDescription = null,
tint = SuccessGreen, tint = Color(0xFF10B981),
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(
text = text, text = text,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
} }
} }

View File

@ -5,10 +5,16 @@ import android.net.Uri
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts 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.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items 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.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.* import androidx.compose.material.icons.filled.*
@ -18,14 +24,19 @@ import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import com.shaarit.data.export.BookmarkImporter 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.text.SimpleDateFormat
import java.util.* import java.util.*
@ -34,10 +45,12 @@ import java.util.*
fun SettingsScreen( fun SettingsScreen(
onNavigateBack: () -> Unit, onNavigateBack: () -> Unit,
onNavigateToDashboard: () -> Unit, onNavigateToDashboard: () -> Unit,
viewModel: SettingsViewModel = hiltViewModel() viewModel: SettingsViewModel = hiltViewModel(),
themePreferences: ThemePreferences = viewModel.themePreferences
) { ) {
val context = LocalContext.current val context = LocalContext.current
val uiState by viewModel.uiState.collectAsState() val uiState by viewModel.uiState.collectAsState()
val currentTheme by themePreferences.currentTheme.collectAsState()
// Export JSON // Export JSON
val exportJsonLauncher = rememberLauncherForActivityResult( val exportJsonLauncher = rememberLauncherForActivityResult(
@ -101,8 +114,21 @@ fun SettingsScreen(
contentPadding = PaddingValues(16.dp), contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(8.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 // AI Section - Gemini API Key
item { item {
Spacer(modifier = Modifier.height(16.dp))
SettingsSection(title = "Intelligence Artificielle") 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
)
}
}

View File

@ -11,6 +11,7 @@ import com.shaarit.data.sync.SyncManager
import com.shaarit.data.sync.SyncState import com.shaarit.data.sync.SyncState
import com.shaarit.data.worker.LinkHealthCheckWorker import com.shaarit.data.worker.LinkHealthCheckWorker
import com.shaarit.domain.usecase.ClassifyBookmarksUseCase import com.shaarit.domain.usecase.ClassifyBookmarksUseCase
import com.shaarit.ui.theme.ThemePreferences
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -29,7 +30,8 @@ class SettingsViewModel @Inject constructor(
private val linkDao: LinkDao, private val linkDao: LinkDao,
private val classifyBookmarksUseCase: ClassifyBookmarksUseCase, private val classifyBookmarksUseCase: ClassifyBookmarksUseCase,
private val tokenManager: TokenManager, private val tokenManager: TokenManager,
private val workManager: WorkManager private val workManager: WorkManager,
val themePreferences: ThemePreferences
) : ViewModel() { ) : ViewModel() {
private val _uiState = MutableStateFlow(SettingsUiState()) private val _uiState = MutableStateFlow(SettingsUiState())

View File

@ -30,7 +30,7 @@ import com.shaarit.domain.model.ShaarliTag
import com.shaarit.ui.components.GlassCard import com.shaarit.ui.components.GlassCard
import com.shaarit.ui.components.PremiumTextField import com.shaarit.ui.components.PremiumTextField
import com.shaarit.ui.components.TagChip import com.shaarit.ui.components.TagChip
import com.shaarit.ui.theme.* import com.shaarit.ui.theme.Typography
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -48,7 +48,7 @@ fun TagsScreen(
.background( .background(
brush = brush =
Brush.verticalGradient( Brush.verticalGradient(
colors = listOf(DeepNavy, DarkNavy) colors = listOf(MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.surface)
) )
) )
) { ) {
@ -67,14 +67,14 @@ fun TagsScreen(
Icon( Icon(
Icons.Default.ArrowBack, Icons.Default.ArrowBack,
contentDescription = "Back", contentDescription = "Back",
tint = TextPrimary tint = MaterialTheme.colorScheme.onBackground
) )
} }
}, },
colors = colors =
TopAppBarDefaults.topAppBarColors( TopAppBarDefaults.topAppBarColors(
containerColor = DeepNavy.copy(alpha = 0.9f), containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.9f),
titleContentColor = TextPrimary titleContentColor = MaterialTheme.colorScheme.onBackground
) )
) )
@ -85,7 +85,7 @@ fun TagsScreen(
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp), modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
placeholder = "Search tags...", placeholder = "Search tags...",
leadingIcon = { leadingIcon = {
Icon(Icons.Default.Search, contentDescription = null, tint = TextMuted) Icon(Icons.Default.Search, contentDescription = null, tint = MaterialTheme.colorScheme.outline)
}, },
trailingIcon = { trailingIcon = {
if (searchQuery.isNotEmpty()) { if (searchQuery.isNotEmpty()) {
@ -93,7 +93,7 @@ fun TagsScreen(
Icon( Icon(
Icons.Default.Close, Icons.Default.Close,
contentDescription = "Clear", contentDescription = "Clear",
tint = TextMuted tint = MaterialTheme.colorScheme.outline
) )
} }
} }
@ -103,7 +103,7 @@ fun TagsScreen(
when (val state = uiState) { when (val state = uiState) {
is TagsUiState.Loading -> { is TagsUiState.Loading -> {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CircularProgressIndicator(color = CyanPrimary) CircularProgressIndicator(color = MaterialTheme.colorScheme.primary)
} }
} }
is TagsUiState.Error -> { is TagsUiState.Error -> {
@ -112,13 +112,13 @@ fun TagsScreen(
Text( Text(
"Failed to load tags", "Failed to load tags",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
color = ErrorRed color = MaterialTheme.colorScheme.error
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
state.message, state.message,
style = MaterialTheme.typography.bodyMedium, 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) { private fun TagsGridView(tags: List<ShaarliTag>, onTagClick: (ShaarliTag) -> Unit) {
if (tags.isEmpty()) { if (tags.isEmpty()) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { 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 { } else {
LazyVerticalGrid( LazyVerticalGrid(
@ -153,13 +153,13 @@ private fun TagsGridView(tags: List<ShaarliTag>, onTagClick: (ShaarliTag) -> Uni
@Composable @Composable
private fun TagGridItem(tag: ShaarliTag, onClick: () -> Unit) { 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)) { Column(modifier = Modifier.padding(4.dp)) {
Text( Text(
text = "#${tag.name}", text = "#${tag.name}",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = CyanPrimary, color = MaterialTheme.colorScheme.primary,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -167,7 +167,7 @@ private fun TagGridItem(tag: ShaarliTag, onClick: () -> Unit) {
Text( Text(
text = "${tag.occurrences} links", text = "${tag.occurrences} links",
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }

View File

@ -40,7 +40,7 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex import androidx.compose.ui.zIndex
import com.shaarit.ui.theme.* import com.shaarit.ui.theme.Typography
import dev.jeziellago.compose.markdowntext.MarkdownText import dev.jeziellago.compose.markdowntext.MarkdownText
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -210,10 +210,10 @@ fun SimpleMarkdownEditor(
// Zone d'édition principale (sans la toolbar - elle sera flottante) // Zone d'édition principale (sans la toolbar - elle sera flottante)
Box( Box(
modifier = modifier modifier = modifier
.background(CardBackgroundElevated, RoundedCornerShape(12.dp)) .background(MaterialTheme.colorScheme.primaryContainer, RoundedCornerShape(12.dp))
.border( .border(
width = if (internalState.isFocused) 2.dp else 1.dp, 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) shape = RoundedCornerShape(12.dp)
) )
.padding(16.dp) .padding(16.dp)
@ -240,11 +240,11 @@ fun SimpleMarkdownEditor(
.focusRequester(focusRequester) .focusRequester(focusRequester)
.onFocusChanged { internalState.isFocused = it.isFocused }, .onFocusChanged { internalState.isFocused = it.isFocused },
textStyle = TextStyle( textStyle = TextStyle(
color = TextPrimary, color = MaterialTheme.colorScheme.onBackground,
fontSize = if (isNoteMode) 17.sp else 15.sp, fontSize = if (isNoteMode) 17.sp else 15.sp,
lineHeight = if (isNoteMode) 26.sp else 22.sp lineHeight = if (isNoteMode) 26.sp else 22.sp
), ),
cursorBrush = SolidColor(CyanPrimary), cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
readOnly = readOnly, readOnly = readOnly,
keyboardOptions = KeyboardOptions( keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Sentences, capitalization = KeyboardCapitalization.Sentences,
@ -254,7 +254,7 @@ fun SimpleMarkdownEditor(
if (internalState.textFieldValue.text.isEmpty()) { if (internalState.textFieldValue.text.isEmpty()) {
Text( Text(
text = placeholder, text = placeholder,
color = TextSecondary.copy(alpha = 0.6f), color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
fontSize = if (isNoteMode) 17.sp else 15.sp fontSize = if (isNoteMode) 17.sp else 15.sp
) )
} }
@ -366,7 +366,7 @@ fun FloatingMarkdownToolbar(
modifier = modifier.padding(bottom = bottomPadding) modifier = modifier.padding(bottom = bottomPadding)
) { ) {
Surface( Surface(
color = CardBackground, color = MaterialTheme.colorScheme.surfaceVariant,
shadowElevation = 16.dp, shadowElevation = 16.dp,
tonalElevation = 8.dp, tonalElevation = 8.dp,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
@ -417,7 +417,7 @@ fun MarkorStyleToolbar(
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
Surface( Surface(
color = CardBackground.copy(alpha = 0.95f), color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.95f),
shadowElevation = 8.dp, shadowElevation = 8.dp,
modifier = modifier.fillMaxWidth() modifier = modifier.fillMaxWidth()
) { ) {
@ -449,7 +449,7 @@ private fun MarkorToolButton(
Surface( Surface(
onClick = onClick, onClick = onClick,
shape = RoundedCornerShape(8.dp), shape = RoundedCornerShape(8.dp),
color = CardBackgroundElevated, color = MaterialTheme.colorScheme.primaryContainer,
modifier = Modifier.size(42.dp) modifier = Modifier.size(42.dp)
) { ) {
Box( Box(
@ -459,7 +459,7 @@ private fun MarkorToolButton(
Icon( Icon(
imageVector = tool.icon, imageVector = tool.icon,
contentDescription = tool.label, contentDescription = tool.label,
tint = TextSecondary, tint = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(22.dp) modifier = Modifier.size(22.dp)
) )
} }
@ -644,21 +644,21 @@ fun MarkdownPreview(
Box( Box(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.background(CardBackgroundElevated, RoundedCornerShape(12.dp)) .background(MaterialTheme.colorScheme.primaryContainer, RoundedCornerShape(12.dp))
.border(1.dp, CyanPrimary.copy(alpha = 0.2f), RoundedCornerShape(12.dp)) .border(1.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.2f), RoundedCornerShape(12.dp))
.padding(16.dp) .padding(16.dp)
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
) { ) {
if (markdown.isBlank()) { if (markdown.isBlank()) {
Text( Text(
text = "Aucun contenu à prévisualiser...", text = "Aucun contenu à prévisualiser...",
color = TextSecondary.copy(alpha = 0.6f), color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
style = MaterialTheme.typography.bodyMedium style = MaterialTheme.typography.bodyMedium
) )
} else { } else {
MarkdownText( MarkdownText(
markdown = markdown, markdown = markdown,
color = TextPrimary, color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
} }
@ -786,8 +786,8 @@ private fun ModeToggleButton(
Surface( Surface(
onClick = onClick, onClick = onClick,
shape = RoundedCornerShape(8.dp), shape = RoundedCornerShape(8.dp),
color = if (isSelected) CyanPrimary.copy(alpha = 0.15f) else CardBackground, color = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.15f) else MaterialTheme.colorScheme.surfaceVariant,
border = if (isSelected) androidx.compose.foundation.BorderStroke(1.dp, CyanPrimary) else null, border = if (isSelected) androidx.compose.foundation.BorderStroke(1.dp, MaterialTheme.colorScheme.primary) else null,
modifier = modifier modifier = modifier
) { ) {
Row( Row(
@ -798,13 +798,13 @@ private fun ModeToggleButton(
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
tint = if (isSelected) CyanPrimary else TextSecondary, tint = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
Spacer(modifier = Modifier.width(6.dp)) Spacer(modifier = Modifier.width(6.dp))
Text( Text(
text = label, text = label,
color = if (isSelected) CyanPrimary else TextSecondary, color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
fontWeight = if (isSelected) FontWeight.Medium else FontWeight.Normal fontWeight = if (isSelected) FontWeight.Medium else FontWeight.Normal
) )
@ -820,13 +820,13 @@ fun MarkdownHelp(modifier: Modifier = Modifier) {
Column( Column(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.background(CardBackground.copy(alpha = 0.5f), RoundedCornerShape(8.dp)) .background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f), RoundedCornerShape(8.dp))
.padding(12.dp) .padding(12.dp)
) { ) {
Text( Text(
text = "Formatage rapide :", text = "Formatage rapide :",
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextMuted, color = MaterialTheme.colorScheme.outline,
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium
) )
Spacer(modifier = Modifier.height(6.dp)) Spacer(modifier = Modifier.height(6.dp))
@ -850,13 +850,13 @@ fun MarkdownHelp(modifier: Modifier = Modifier) {
@Composable @Composable
private fun HelpChip(text: String) { private fun HelpChip(text: String) {
Surface( Surface(
color = CardBackgroundElevated, color = MaterialTheme.colorScheme.primaryContainer,
shape = RoundedCornerShape(4.dp) shape = RoundedCornerShape(4.dp)
) { ) {
Text( Text(
text = text, text = text,
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = TextSecondary, color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace
) )

View File

@ -24,7 +24,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.shaarit.ui.theme.* import com.shaarit.ui.theme.Typography
/** A glassmorphism-styled card with subtle border glow effect */ /** A glassmorphism-styled card with subtle border glow effect */
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@ -33,7 +33,7 @@ fun GlassCard(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onClick: (() -> Unit)? = null, onClick: (() -> Unit)? = null,
onLongClick: (() -> Unit)? = null, onLongClick: (() -> Unit)? = null,
glowColor: Color = CyanPrimary, glowColor: Color = MaterialTheme.colorScheme.primary,
content: @Composable ColumnScope.() -> Unit content: @Composable ColumnScope.() -> Unit
) { ) {
val interactionSource = remember { MutableInteractionSource() } val interactionSource = remember { MutableInteractionSource() }
@ -77,8 +77,8 @@ fun GlassCard(
Brush.verticalGradient( Brush.verticalGradient(
colors = colors =
listOf( listOf(
CardBackground.copy(alpha = 0.95f), MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.95f),
CardBackgroundElevated.copy( MaterialTheme.colorScheme.primaryContainer.copy(
alpha = 0.9f alpha = 0.9f
) )
) )
@ -134,9 +134,9 @@ fun GradientButton(
Brush.horizontalGradient( Brush.horizontalGradient(
colors = colors =
if (enabled) { if (enabled) {
listOf(TealSecondary, CyanPrimary) listOf(MaterialTheme.colorScheme.secondary, MaterialTheme.colorScheme.primary)
} else { } else {
listOf(TextMuted, TextMuted) listOf(MaterialTheme.colorScheme.outline, MaterialTheme.colorScheme.outline)
} }
) )
@ -150,8 +150,8 @@ fun GradientButton(
.shadow( .shadow(
elevation = if (isPressed) 4.dp else 12.dp, elevation = if (isPressed) 4.dp else 12.dp,
shape = RoundedCornerShape(12.dp), shape = RoundedCornerShape(12.dp),
ambientColor = CyanPrimary.copy(alpha = 0.3f), ambientColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f),
spotColor = CyanPrimary.copy(alpha = 0.4f) spotColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.4f)
) )
.clip(RoundedCornerShape(12.dp)) .clip(RoundedCornerShape(12.dp))
.background(gradient) .background(gradient)
@ -176,7 +176,7 @@ fun GradientButton(
text = text, text = text,
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = DeepNavy color = MaterialTheme.colorScheme.background
) )
} }
} }
@ -194,19 +194,19 @@ fun TagChip(
val backgroundColor by val backgroundColor by
animateColorAsState( animateColorAsState(
targetValue = 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) animationSpec = tween(200)
) )
val borderColor by val borderColor by
animateColorAsState( 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) animationSpec = tween(200)
) )
val textColor by val textColor by
animateColorAsState( animateColorAsState(
targetValue = if (isSelected) CyanPrimary else TextSecondary, targetValue = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
animationSpec = tween(200) animationSpec = tween(200)
) )
@ -258,7 +258,7 @@ fun PremiumTextField(
onValueChange = onValueChange, onValueChange = onValueChange,
modifier = modifier, modifier = modifier,
label = label?.let { { Text(it) } }, label = label?.let { { Text(it) } },
placeholder = placeholder?.let { { Text(it, color = TextMuted) } }, placeholder = placeholder?.let { { Text(it, color = MaterialTheme.colorScheme.outline) } },
singleLine = singleLine, singleLine = singleLine,
minLines = minLines, minLines = minLines,
leadingIcon = leadingIcon, leadingIcon = leadingIcon,
@ -278,15 +278,15 @@ fun PremiumTextField(
}, },
colors = colors =
OutlinedTextFieldDefaults.colors( OutlinedTextFieldDefaults.colors(
focusedBorderColor = CyanPrimary, focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = SurfaceVariant, unfocusedBorderColor = MaterialTheme.colorScheme.outlineVariant,
focusedLabelColor = CyanPrimary, focusedLabelColor = MaterialTheme.colorScheme.primary,
unfocusedLabelColor = TextSecondary, unfocusedLabelColor = MaterialTheme.colorScheme.onSurfaceVariant,
cursorColor = CyanPrimary, cursorColor = MaterialTheme.colorScheme.primary,
focusedContainerColor = CardBackground.copy(alpha = 0.5f), focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f),
unfocusedContainerColor = CardBackground.copy(alpha = 0.3f), unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f),
errorBorderColor = ErrorRed, errorBorderColor = MaterialTheme.colorScheme.error,
errorLabelColor = ErrorRed errorLabelColor = MaterialTheme.colorScheme.error
), ),
shape = RoundedCornerShape(12.dp) shape = RoundedCornerShape(12.dp)
) )
@ -310,13 +310,13 @@ fun SectionHeader(
text = title, text = title,
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = TextPrimary color = MaterialTheme.colorScheme.onBackground
) )
if (subtitle != null) { if (subtitle != null) {
Text( Text(
text = subtitle, text = subtitle,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = TextSecondary color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }

View File

@ -7,6 +7,7 @@ import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier 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.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.shaarit.ui.theme.CardBackground
import com.shaarit.ui.theme.CardBackgroundElevated
fun Modifier.shimmerEffect(): Modifier = composed { fun Modifier.shimmerEffect(): Modifier = composed {
val transition = rememberInfiniteTransition(label = "shimmer") val transition = rememberInfiniteTransition(label = "shimmer")
@ -53,7 +52,7 @@ fun SkeletonLinkCard(
.fillMaxWidth() .fillMaxWidth()
.height(200.dp) .height(200.dp)
.clip(RoundedCornerShape(16.dp)), // Match GlassCard shape .clip(RoundedCornerShape(16.dp)), // Match GlassCard shape
color = CardBackground.copy(alpha = 0.5f) color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier

View 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"
}
}

View File

@ -1,18 +1,12 @@
package com.shaarit.ui.theme package com.shaarit.ui.theme
import android.app.Activity import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme 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.Composable
import androidx.compose.runtime.SideEffect import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
@ -47,7 +41,8 @@ val GradientEnd = Color(0xFF00D4AA)
val Purple = Color(0xFFA855F7) val Purple = Color(0xFFA855F7)
val PurpleLight = Color(0xFFC084FC) val PurpleLight = Color(0xFFC084FC)
private val DarkColorScheme = // ── Default Theme (ShaarIt) ──
private val DefaultDarkColorScheme =
darkColorScheme( darkColorScheme(
primary = CyanPrimary, primary = CyanPrimary,
onPrimary = DeepNavy, onPrimary = DeepNavy,
@ -73,64 +68,414 @@ private val DarkColorScheme =
onErrorContainer = Color(0xFFFCA5A5) onErrorContainer = Color(0xFFFCA5A5)
) )
private val LightColorScheme = // ── GitHub (Smooth Dark) ──
lightColorScheme( private val GitHubDarkColorScheme =
primary = Color(0xFF0891B2), darkColorScheme(
onPrimary = Color.White, primary = Color(0xFF58A6FF),
primaryContainer = Color(0xFFCFFAFE), onPrimary = Color(0xFF0D1117),
onPrimaryContainer = Color(0xFF164E63), primaryContainer = Color(0xFF1F2937),
secondary = Color(0xFF0284C7), onPrimaryContainer = Color(0xFF79C0FF),
onSecondary = Color.White, secondary = Color(0xFF3FB950),
background = Color(0xFFF8FAFC), onSecondary = Color(0xFF0D1117),
onBackground = Color(0xFF0F172A), secondaryContainer = Color(0xFF1C2D22),
surface = Color.White, onSecondaryContainer = Color(0xFF56D364),
onSurface = Color(0xFF0F172A), tertiary = Color(0xFFD2A8FF),
surfaceVariant = Color(0xFFF1F5F9), onTertiary = Color(0xFF0D1117),
onSurfaceVariant = Color(0xFF475569) 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 @Composable
fun ShaarItTheme( fun ShaarItTheme(
darkTheme: Boolean = isSystemInDarkTheme(), appTheme: AppTheme = AppTheme.DEFAULT,
dynamicColor: Boolean = true, // Enable Material You by default
oledMode: Boolean = false, // Pure black for OLED screens
content: @Composable () -> Unit content: @Composable () -> Unit
) { ) {
val context = LocalContext.current // Always use the explicit color scheme for the selected theme
val colorScheme = getColorSchemeForTheme(appTheme)
val colorScheme = // All custom themes are dark
when { val isEffectivelyDark = true
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
}
val view = LocalView.current val view = LocalView.current
if (!view.isInEditMode) { if (!view.isInEditMode) {
@ -138,7 +483,7 @@ fun ShaarItTheme(
val window = (view.context as Activity).window val window = (view.context as Activity).window
window.statusBarColor = colorScheme.background.toArgb() window.statusBarColor = colorScheme.background.toArgb()
window.navigationBarColor = colorScheme.background.toArgb() window.navigationBarColor = colorScheme.background.toArgb()
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !isEffectivelyDark
} }
} }