feat: Migrate UI theme system from hardcoded colors to Material3 dynamic theming
- Inject ThemePreferences into MainActivity and apply dynamic theme selection - Replace all hardcoded color references (DeepNavy, DarkNavy, CyanPrimary, TextPrimary, etc.) with MaterialTheme.colorScheme equivalents throughout AddLinkScreen and LoginScreen - Update component colors to use Material3 color roles (primary, onBackground, surfaceVariant, outline, etc.) - Migrate GlassCard, buttons, text fields, switches, and progress
This commit is contained in:
parent
80ab3009aa
commit
98f2ef2e7e
@ -8,18 +8,25 @@ import androidx.activity.enableEdgeToEdge
|
|||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.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
|
||||||
|
|||||||
@ -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)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -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())
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
62
app/src/main/java/com/shaarit/ui/theme/AppTheme.kt
Normal file
62
app/src/main/java/com/shaarit/ui/theme/AppTheme.kt
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package com.shaarit.ui.theme
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
enum class AppTheme(
|
||||||
|
val displayName: String,
|
||||||
|
val description: String
|
||||||
|
) {
|
||||||
|
DEFAULT("ShaarIt", "Le thème original de l'application"),
|
||||||
|
GITHUB("GitHub", "Mode sombre équilibré, contrastes doux"),
|
||||||
|
LINEAR("Linear", "Dégradés subtils, teintes sombres douces"),
|
||||||
|
SPOTIFY("Spotify", "Noir pur avec accents verts"),
|
||||||
|
NOTION("Notion", "Sombre épuré, optimisé pour la lecture"),
|
||||||
|
DISCORD("Discord", "Gris bleuté, référence des interfaces communautaires"),
|
||||||
|
DRACULA("Dracula", "Sombre emblématique, accents rose, violet et vert"),
|
||||||
|
ONE_DARK_PRO("One Dark Pro", "Inspiré d'Atom, contraste doux bleuté"),
|
||||||
|
TOKYO_NIGHT("Tokyo Night", "Néons de Tokyo, bleu profond et couleurs électriques"),
|
||||||
|
NORD("Nord", "Style arctique, bleus froids et gris clairs sereins"),
|
||||||
|
NIGHT_OWL("Night Owl", "Optimisé pour la nuit, accessibilité renforcée"),
|
||||||
|
ANTHRACITE("Anthracite", "Gris mat Material Design, réduit la fatigue oculaire"),
|
||||||
|
CYBERPUNK("Cyberpunk", "Néons futuristes, cyan et magenta vibrants"),
|
||||||
|
NAVY_ELEGANCE("Navy Élégance", "Bleu marine profond, touches dorées luxueuses"),
|
||||||
|
EARTHY("Tons Terreux", "Verts forêt et bruns chocolat, ambiance organique");
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromName(name: String): AppTheme {
|
||||||
|
return entries.find { it.name == name } ?: DEFAULT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class ThemePreferences @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context
|
||||||
|
) {
|
||||||
|
private val prefs: SharedPreferences =
|
||||||
|
context.getSharedPreferences("theme_prefs", Context.MODE_PRIVATE)
|
||||||
|
|
||||||
|
private val _currentTheme = MutableStateFlow(loadTheme())
|
||||||
|
val currentTheme: StateFlow<AppTheme> = _currentTheme.asStateFlow()
|
||||||
|
|
||||||
|
private fun loadTheme(): AppTheme {
|
||||||
|
val name = prefs.getString(KEY_THEME, AppTheme.DEFAULT.name) ?: AppTheme.DEFAULT.name
|
||||||
|
return AppTheme.fromName(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setTheme(theme: AppTheme) {
|
||||||
|
prefs.edit().putString(KEY_THEME, theme.name).apply()
|
||||||
|
_currentTheme.value = theme
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val KEY_THEME = "selected_theme"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,18 +1,12 @@
|
|||||||
package com.shaarit.ui.theme
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user