8fdd22bc98
- FilesScreen: long-press enters selection mode, bulk share/delete toolbar, BackHandler - FilesViewModel: ShareMultiple action, isSelectionMode/selectedCount state, download-to-cache for open/share - FileWatchService: recursive FileObserver per subdirectory; unified notification updated with sync result via WorkManager flow observation - SyncWorker: silent flag suppresses notifications when triggered by watcher; emits KEY_RESULT_SUMMARY output data - Passbolt-inspired dark theme (Red700/Red500 primary, near-black surface) - App icon: circular AutoSync-style sync arrows (cyan gradient, deep navy background) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
80 lines
3.0 KiB
Kotlin
80 lines
3.0 KiB
Kotlin
package com.syncflow.ui.theme
|
|
|
|
import android.app.Activity
|
|
import androidx.compose.foundation.isSystemInDarkTheme
|
|
import androidx.compose.material3.*
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.SideEffect
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.platform.LocalView
|
|
import androidx.compose.ui.text.TextStyle
|
|
import androidx.compose.ui.text.font.FontWeight
|
|
import androidx.compose.ui.unit.sp
|
|
import androidx.core.view.WindowCompat
|
|
|
|
private val LightColors = lightColorScheme(
|
|
primary = Red700,
|
|
onPrimary = Color.White,
|
|
primaryContainer = Red50,
|
|
onPrimaryContainer = Red900,
|
|
secondary = Orange700,
|
|
onSecondary = Color.White,
|
|
secondaryContainer = Orange100,
|
|
tertiary = Amber500,
|
|
tertiaryContainer = Amber100,
|
|
background = Gray50,
|
|
surface = Color.White,
|
|
surfaceVariant = Gray100,
|
|
onSurface = Gray900,
|
|
onSurfaceVariant = Gray600,
|
|
error = RedError,
|
|
errorContainer = Red50,
|
|
outline = Gray200,
|
|
)
|
|
|
|
private val DarkColors = darkColorScheme(
|
|
primary = Red500,
|
|
onPrimary = Color.White,
|
|
primaryContainer = Red900,
|
|
onPrimaryContainer = Red100,
|
|
secondary = Color(0xFFFF7043),
|
|
onSecondary = Color.White,
|
|
secondaryContainer = Color(0xFF4E1500),
|
|
tertiary = Amber500,
|
|
tertiaryContainer = Color(0xFF3E2700),
|
|
background = Color(0xFF0F0F0F),
|
|
surface = Color(0xFF1C1C1C),
|
|
surfaceVariant = Color(0xFF2A2A2A),
|
|
onSurface = Color(0xFFEAEAEA),
|
|
onSurfaceVariant = Color(0xFF9E9E9E),
|
|
error = Color(0xFFFF5252),
|
|
errorContainer = Color(0xFF5C0000),
|
|
outline = Color(0xFF3D3D3D),
|
|
)
|
|
|
|
private val AppTypography = Typography(
|
|
titleLarge = TextStyle(fontWeight = FontWeight.Bold, fontSize = 22.sp, letterSpacing = (-0.5).sp),
|
|
titleMedium = TextStyle(fontWeight = FontWeight.SemiBold, fontSize = 16.sp, letterSpacing = (-0.25).sp),
|
|
titleSmall = TextStyle(fontWeight = FontWeight.SemiBold, fontSize = 14.sp, letterSpacing = 0.sp),
|
|
labelMedium = TextStyle(fontWeight = FontWeight.Medium, fontSize = 12.sp, letterSpacing = 0.1.sp),
|
|
labelSmall = TextStyle(fontWeight = FontWeight.Medium, fontSize = 11.sp, letterSpacing = 0.1.sp),
|
|
)
|
|
|
|
@Composable
|
|
fun SyncFlowTheme(
|
|
darkTheme: Boolean = isSystemInDarkTheme(),
|
|
content: @Composable () -> Unit,
|
|
) {
|
|
val colorScheme = if (darkTheme) DarkColors else LightColors
|
|
val view = LocalView.current
|
|
if (!view.isInEditMode) {
|
|
SideEffect {
|
|
val window = (view.context as Activity).window
|
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
|
window.statusBarColor = android.graphics.Color.TRANSPARENT
|
|
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
|
|
}
|
|
}
|
|
MaterialTheme(colorScheme = colorScheme, typography = AppTypography, content = content)
|
|
}
|