diff --git a/app/src/main/java/com/rosetta/messenger/ui/auth/SetPasswordScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/auth/SetPasswordScreen.kt index 52c2725..7e0bb54 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/auth/SetPasswordScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/auth/SetPasswordScreen.kt @@ -9,12 +9,14 @@ import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.* import compose.icons.TablerIcons import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType @@ -75,7 +77,15 @@ fun SetPasswordScreen( var visible by remember { mutableStateOf(false) } // Track keyboard visibility - val view = androidx.compose.ui.platform.LocalView.current + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as android.app.Activity).window + val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view) + insetsController.isAppearanceLightStatusBars = !isDarkTheme + window.statusBarColor = android.graphics.Color.TRANSPARENT + } + } var isKeyboardVisible by remember { mutableStateOf(false) } DisposableEffect(view) { @@ -106,7 +116,7 @@ fun SetPasswordScreen( ) { IconButton(onClick = onBack, enabled = !isCreating) { Icon( - imageVector = TablerIcons.ArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = textColor.copy(alpha = 0.6f) ) @@ -280,7 +290,7 @@ fun SetPasswordScreen( else -> Color(0xFF4CAF50) } Icon( - imageVector = TablerIcons.Shield, + painter = TelegramIcons.Secret, contentDescription = null, tint = strengthColor, modifier = Modifier.size(16.dp) @@ -306,7 +316,7 @@ fun SetPasswordScreen( verticalAlignment = Alignment.Top ) { Icon( - imageVector = TablerIcons.AlertTriangle, + painter = TelegramIcons.Warning, contentDescription = null, tint = Color(0xFFE53935), modifier = Modifier.size(16.dp) @@ -446,7 +456,7 @@ fun SetPasswordScreen( verticalAlignment = Alignment.Top ) { Icon( - imageVector = TablerIcons.InfoCircle, + painter = TelegramIcons.Info, contentDescription = null, tint = PrimaryBlue, modifier = Modifier.size(20.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/auth/UnlockScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/auth/UnlockScreen.kt index 6e53dcd..0b484f3 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/auth/UnlockScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/auth/UnlockScreen.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material3.* import compose.icons.TablerIcons import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -504,7 +505,7 @@ fun UnlockScreen( if (isSelected) { Icon( - TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = null, tint = PrimaryBlue, modifier = Modifier.size(20.dp) @@ -645,7 +646,7 @@ fun UnlockScreen( ) } else { Icon( - imageVector = TablerIcons.LockOpen, + painter = TelegramIcons.Unlock, contentDescription = null, modifier = Modifier.size(20.dp) ) @@ -663,7 +664,7 @@ fun UnlockScreen( enabled = !isUnlocking ) { Icon( - imageVector = TablerIcons.Fingerprint, + painter = TelegramIcons.Fingerprint, contentDescription = null, tint = PrimaryBlue, modifier = Modifier.size(22.dp) @@ -719,7 +720,7 @@ fun UnlockScreen( TextButton(onClick = onSwitchAccount) { Icon( - imageVector = TablerIcons.UserPlus, + painter = TelegramIcons.AddContact, contentDescription = null, tint = PrimaryBlue, modifier = Modifier.size(18.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt index 9367aa3..5e83c1a 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt @@ -27,6 +27,9 @@ import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* +import compose.icons.TablerIcons +import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.collectAsState @@ -117,6 +120,15 @@ fun ChatDetailScreen( val database = RosettaDatabase.getDatabase(context) val hapticFeedback = LocalHapticFeedback.current + // 🔇 Mute state — read from PreferencesManager + val preferencesManager = remember { com.rosetta.messenger.data.PreferencesManager(context) } + val isChatMuted = remember { mutableStateOf(false) } + LaunchedEffect(currentUserPublicKey, user.publicKey) { + if (currentUserPublicKey.isNotBlank()) { + isChatMuted.value = preferencesManager.isChatMuted(currentUserPublicKey, user.publicKey) + } + } + // UI Theme val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFF2F2F7) val textColor = if (isDarkTheme) Color.White else Color.Black @@ -192,17 +204,24 @@ fun ChatDetailScreen( var imageViewerSourceBounds by remember { mutableStateOf(null) } var imageViewerImages by remember { mutableStateOf>(emptyList()) } - // 🎨 Управление статус баром - DisposableEffect(isDarkTheme, showImageViewer, window, view) { - if (showImageViewer) { - // 📸 При просмотре фото - чёрные system bars - SystemBarsStyleUtils.applyFullscreenDark(window, view) - } else { - // Обычный режим чата - SystemBarsStyleUtils.applyChatStatusBar(window, view, isDarkTheme) + // 🎨 Управление статус баром — ВСЕГДА чёрные иконки в светлой теме + if (!view.isInEditMode) { + SideEffect { + if (showImageViewer) { + SystemBarsStyleUtils.applyFullscreenDark(window, view) + } else { + if (window != null && view != null) { + val ic = androidx.core.view.WindowCompat.getInsetsController(window, view) + window.statusBarColor = android.graphics.Color.TRANSPARENT + ic.isAppearanceLightStatusBars = !isDarkTheme + } + } } + } + DisposableEffect(Unit) { onDispose { + // Восстановить при уходе с экрана SystemBarsStyleUtils.applyChatStatusBar(window, view, isDarkTheme) } } @@ -562,16 +581,10 @@ fun ChatDetailScreen( } ) { Icon( - Icons.Default - .Close, + painter = TelegramIcons.Close, contentDescription = "Cancel", - tint = - if (isDarkTheme - ) - Color.White - else - Color.Black, + tint = headerIconColor, modifier = Modifier.size( 24.dp @@ -657,12 +670,7 @@ fun ChatDetailScreen( .ContentCopy, contentDescription = "Copy", - tint = - if (isDarkTheme - ) - Color.White - else - Color.Black, + tint = headerIconColor, modifier = Modifier.size( 22.dp @@ -697,12 +705,7 @@ fun ChatDetailScreen( .Delete, contentDescription = "Delete", - tint = - if (isDarkTheme - ) - Color.White - else - Color.Black, + tint = headerIconColor, modifier = Modifier.size( 22.dp @@ -735,8 +738,7 @@ fun ChatDetailScreen( ) ) { Icon( - Icons.Default - .KeyboardArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = @@ -749,7 +751,7 @@ fun ChatDetailScreen( ), modifier = Modifier.size( - 32.dp + 28.dp ) ) } @@ -987,6 +989,16 @@ fun ChatDetailScreen( isDarkTheme ) } + // 🔇 Mute icon + if (isChatMuted.value) { + Spacer(modifier = Modifier.width(4.dp)) + Icon( + painter = TelegramIcons.Mute, + contentDescription = "Muted", + modifier = Modifier.size(16.dp), + tint = secondaryTextColor + ) + } } // Typing indicator или // subtitle @@ -1886,6 +1898,16 @@ fun ChatDetailScreen( avatarRepository, onLongClick = { // 📳 Haptic feedback при долгом нажатии + // Не разрешаем выделять avatar-сообщения + val hasAvatar = + message.attachments + .any { + it.type == + AttachmentType + .AVATAR + } + if (hasAvatar) return@MessageBubble + hapticFeedback .performHapticFeedback( HapticFeedbackType @@ -1922,7 +1944,14 @@ fun ChatDetailScreen( } }, onClick = { - if (isSelectionMode + val hasAvatar = + message.attachments + .any { + it.type == + AttachmentType + .AVATAR + } + if (isSelectionMode && !hasAvatar ) { selectedMessages = if (selectedMessages diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatsListScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatsListScreen.kt index d131b03..b59ddca 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatsListScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatsListScreen.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.gestures.awaitFirstDown import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.* @@ -23,6 +24,7 @@ import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.lerp +import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.positionChange @@ -57,6 +59,7 @@ import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.res.painterResource import compose.icons.TablerIcons import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import java.text.SimpleDateFormat import java.util.* import kotlinx.coroutines.launch @@ -220,21 +223,22 @@ fun ChatsListScreen( focusManager.clearFocus() } - // Update status bar appearance — SideEffect overrides global Theme.kt SideEffect - if (!view.isInEditMode) { - SideEffect { - val window = (view.context as android.app.Activity).window - val insetsController = - androidx.core.view.WindowCompat.getInsetsController(window, view) + // Update status bar appearance — only set once on entry, not every recomposition + // This prevents overriding ChatDetailScreen's status bar when ChatsListScreen is in back stack + DisposableEffect(isDarkTheme) { + val window = (view.context as android.app.Activity).window + val insetsController = + androidx.core.view.WindowCompat.getInsetsController(window, view) - // Status bar — always white icons (header is blue) - insetsController.isAppearanceLightStatusBars = false - window.statusBarColor = android.graphics.Color.TRANSPARENT + // Status bar — always white icons (header is blue) + insetsController.isAppearanceLightStatusBars = false + window.statusBarColor = android.graphics.Color.TRANSPARENT - // Navigation bar: показываем только если есть нативные кнопки - com.rosetta.messenger.ui.utils.NavigationModeUtils - .applyNavigationBarVisibility(insetsController, context, isDarkTheme) - } + // Navigation bar + com.rosetta.messenger.ui.utils.NavigationModeUtils + .applyNavigationBarVisibility(insetsController, context, isDarkTheme) + + onDispose { } } // Colors - instant change, no animation - 🔥 КЭШИРУЕМ для производительности @@ -490,21 +494,35 @@ fun ChatsListScreen( ) val headerColor = avatarColors.backgroundColor - // Header с размытым фоном аватарки + // Header с blur аватарки (fallback = голубой) или акцентным цветом (light) Box(modifier = Modifier.fillMaxWidth()) { - BlurredAvatarBackground( - publicKey = accountPublicKey, - avatarRepository = avatarRepository, - fallbackColor = headerColor, - blurRadius = 40f, - alpha = 0.6f, - overlayColors = - BackgroundBlurPresets - .getOverlayColors( - backgroundBlurColorId - ), - isDarkTheme = isDarkTheme - ) + if (isDarkTheme) { + if (backgroundBlurColorId == "solid_blue") { + // Голубой фон + Box( + modifier = Modifier + .matchParentSize() + .background(PrimaryBlueDark) + ) + } else { + // Avatar blur (default) + BlurredAvatarBackground( + publicKey = accountPublicKey, + avatarRepository = avatarRepository, + fallbackColor = PrimaryBlueDark, + blurRadius = 40f, + alpha = 0.6f, + overlayColors = emptyList(), + isDarkTheme = isDarkTheme + ) + } + } else { + Box( + modifier = Modifier + .matchParentSize() + .background(PrimaryBlue) + ) + } // Content поверх фона Column( @@ -689,7 +707,7 @@ fun ChatsListScreen( contentAlignment = Alignment.Center ) { Icon( - imageVector = TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = null, tint = Color.White, modifier = Modifier.size(8.dp) @@ -734,7 +752,7 @@ fun ChatsListScreen( contentAlignment = Alignment.Center ) { Icon( - imageVector = TablerIcons.Plus, + painter = TelegramIcons.Add, contentDescription = "Add Account", tint = if (isDarkTheme) Color(0xFF828282) else Color(0xFF889198), modifier = Modifier.size(22.dp) @@ -866,7 +884,7 @@ fun ChatsListScreen( // Logout DrawerMenuItemEnhanced( - icon = TablerIcons.Logout, + painter = TelegramIcons.Leave, text = "Log Out", iconColor = Color(0xFFFF4444), textColor = Color(0xFFFF4444), @@ -923,7 +941,7 @@ fun ChatsListScreen( navigationIcon = { IconButton(onClick = { selectedChatKeys = emptySet() }) { Icon( - TablerIcons.X, + painter = TelegramIcons.Close, contentDescription = "Close", tint = Color.White ) @@ -950,7 +968,7 @@ fun ChatsListScreen( } }) { Icon( - if (allMuted) TablerIcons.Bell else TablerIcons.BellOff, + painter = if (allMuted) TelegramIcons.Notifications else TelegramIcons.Mute, contentDescription = if (allMuted) "Unmute" else "Mute", tint = Color.White ) @@ -964,7 +982,7 @@ fun ChatsListScreen( selectedChatKeys = emptySet() }) { Icon( - TablerIcons.Trash, + painter = TelegramIcons.Delete, contentDescription = "Delete", tint = Color.White ) @@ -974,7 +992,7 @@ fun ChatsListScreen( Box { IconButton(onClick = { showSelectionMenu = true }) { Icon( - TablerIcons.DotsVertical, + painter = TelegramIcons.More, contentDescription = "More", tint = Color.White ) @@ -1000,7 +1018,7 @@ fun ChatsListScreen( }, leadingIcon = { Icon( - if (allPinned) TablerIcons.PinnedOff else TablerIcons.Pin, + painter = if (allPinned) TelegramIcons.Unpin else TelegramIcons.Pin, contentDescription = null, tint = if (isDarkTheme) Color.White else Color.Black ) @@ -1028,7 +1046,7 @@ fun ChatsListScreen( }, leadingIcon = { Icon( - TablerIcons.Ban, + painter = TelegramIcons.Block, contentDescription = null, tint = Color(0xFFE53935) ) @@ -1089,10 +1107,10 @@ fun ChatsListScreen( modifier = Modifier .align(Alignment.TopEnd) - .offset(x = 2.dp, y = (-2).dp) - .size(8.dp) + .offset(x = 4.dp, y = (-4).dp) + .size(10.dp) .clip(CircleShape) - .background(if (isDarkTheme) PrimaryBlueDark else PrimaryBlue) + .background(if (isDarkTheme) Color.White else PrimaryBlue) ) } } @@ -1208,7 +1226,7 @@ fun ChatsListScreen( shape = CircleShape ) { Icon( - TablerIcons.Edit, + painter = TelegramIcons.Edit, contentDescription = "New Chat" ) } @@ -1444,9 +1462,55 @@ fun ChatsListScreen( } } + // Track scroll direction to hide/show Requests + val chatListState = rememberLazyListState() + var isRequestsVisible by remember { mutableStateOf(true) } + val hapticFeedback = LocalHapticFeedback.current + + // NestedScroll — ловим направление свайпа даже без скролла + // Для появления: накапливаем pull down дельту, нужен сильный жест + val requestsNestedScroll = remember(hapticFeedback) { + var accumulatedPullDown = 0f + object : androidx.compose.ui.input.nestedscroll.NestedScrollConnection { + override fun onPreScroll( + available: androidx.compose.ui.geometry.Offset, + source: androidx.compose.ui.input.nestedscroll.NestedScrollSource + ): androidx.compose.ui.geometry.Offset { + if (available.y < -10f) { + // Свайп вверх — прячем легко + accumulatedPullDown = 0f + isRequestsVisible = false + } else if (available.y > 0f && !isRequestsVisible) { + // Свайп вниз — накапливаем для появления + accumulatedPullDown += available.y + if (accumulatedPullDown > 120f) { + isRequestsVisible = true + accumulatedPullDown = 0f + hapticFeedback.performHapticFeedback( + HapticFeedbackType.LongPress + ) + } + } else if (available.y <= 0f) { + accumulatedPullDown = 0f + } + return androidx.compose.ui.geometry.Offset.Zero + } + + override suspend fun onPostFling( + consumed: androidx.compose.ui.unit.Velocity, + available: androidx.compose.ui.unit.Velocity + ): androidx.compose.ui.unit.Velocity { + accumulatedPullDown = 0f + return androidx.compose.ui.unit.Velocity.Zero + } + } + } + LazyColumn( + state = chatListState, modifier = Modifier.fillMaxSize() + .nestedScroll(requestsNestedScroll) .background( listBackgroundColor ) @@ -1456,23 +1520,35 @@ fun ChatsListScreen( key = "requests_section" ) { - RequestsSection( - count = - requestsCount, - requests = - requests, - isDarkTheme = - isDarkTheme, - onClick = { - onRequestsClick() + AnimatedVisibility( + visible = isRequestsVisible, + enter = expandVertically( + animationSpec = tween(250, easing = FastOutSlowInEasing) + ) + fadeIn(animationSpec = tween(200)), + exit = shrinkVertically( + animationSpec = tween(250, easing = FastOutSlowInEasing) + ) + fadeOut(animationSpec = tween(200)) + ) { + Column { + RequestsSection( + count = + requestsCount, + requests = + requests, + isDarkTheme = + isDarkTheme, + onClick = { + onRequestsClick() + } + ) + Divider( + color = + dividerColor, + thickness = + 0.5.dp + ) } - ) - Divider( - color = - dividerColor, - thickness = - 0.5.dp - ) + } } } @@ -1980,7 +2056,7 @@ fun ChatItem( if (isMuted) { Spacer(modifier = Modifier.width(4.dp)) Icon( - TablerIcons.BellOff, + painter = TelegramIcons.Mute, contentDescription = "Muted", tint = secondaryTextColor, modifier = Modifier.size(14.dp) @@ -1990,7 +2066,7 @@ fun ChatItem( Row(verticalAlignment = Alignment.CenterVertically) { // Read status Icon( - TablerIcons.Checks, + painter = TelegramIcons.Done, contentDescription = null, tint = PrimaryBlue, modifier = Modifier.size(16.dp) @@ -2028,7 +2104,7 @@ fun ChatItem( // Pin icon if (chat.isPinned) { Icon( - TablerIcons.Pin, + painter = TelegramIcons.Pin, contentDescription = "Pinned", tint = secondaryTextColor.copy( @@ -2262,9 +2338,9 @@ fun SwipeableDialogItem( verticalArrangement = Arrangement.Center ) { Icon( - imageVector = - if (isPinned) TablerIcons.PinnedOff - else TablerIcons.Pin, + painter = + if (isPinned) TelegramIcons.Unpin + else TelegramIcons.Pin, contentDescription = if (isPinned) "Unpin" else "Pin", tint = Color.White, @@ -2303,9 +2379,9 @@ fun SwipeableDialogItem( verticalArrangement = Arrangement.Center ) { Icon( - imageVector = - if (isBlocked) TablerIcons.LockOpen - else TablerIcons.Ban, + painter = + if (isBlocked) TelegramIcons.Unlock + else TelegramIcons.Block, contentDescription = if (isBlocked) "Unblock" else "Block", @@ -2343,7 +2419,7 @@ fun SwipeableDialogItem( verticalArrangement = Arrangement.Center ) { Icon( - imageVector = TablerIcons.Trash, + painter = TelegramIcons.Delete, contentDescription = "Delete", tint = Color.White, modifier = Modifier.size(22.dp) @@ -2742,7 +2818,7 @@ fun DialogItemContent( if (isBlocked) { Spacer(modifier = Modifier.width(4.dp)) Icon( - imageVector = TablerIcons.Lock, + painter = TelegramIcons.Secret, contentDescription = "Blocked", tint = Color(0xFFFF3B30), modifier = Modifier.size(14.dp) @@ -2751,7 +2827,7 @@ fun DialogItemContent( if (isMuted) { Spacer(modifier = Modifier.width(4.dp)) Icon( - imageVector = TablerIcons.BellOff, + painter = TelegramIcons.Mute, contentDescription = "Muted", tint = secondaryTextColor, modifier = Modifier.size(14.dp) @@ -2767,7 +2843,7 @@ fun DialogItemContent( // галочки (прочитано) if (dialog.isSavedMessages) { Icon( - imageVector = TablerIcons.Checks, + painter = TelegramIcons.Done, contentDescription = null, tint = PrimaryBlue, modifier = Modifier.size(16.dp) @@ -2810,8 +2886,8 @@ fun DialogItemContent( // READ (delivered=3) - две синие // галочки Icon( - imageVector = - TablerIcons.Checks, + painter = + TelegramIcons.Done, contentDescription = null, tint = PrimaryBlue, modifier = @@ -2825,8 +2901,8 @@ fun DialogItemContent( 1 -> { // DELIVERED - одна серая галочка Icon( - imageVector = - TablerIcons.Check, + painter = + TelegramIcons.Done, contentDescription = null, tint = secondaryTextColor @@ -2845,8 +2921,8 @@ fun DialogItemContent( else -> { // SENDING (0) - часики Icon( - imageVector = - TablerIcons.Clock, + painter = + TelegramIcons.Clock, contentDescription = "Sending", tint = @@ -2988,7 +3064,7 @@ fun DialogItemContent( Row(verticalAlignment = Alignment.CenterVertically) { Spacer(modifier = Modifier.width(6.dp)) Icon( - imageVector = TablerIcons.Pin, + painter = TelegramIcons.Pin, contentDescription = "Pinned", tint = secondaryTextColor.copy(alpha = 0.5f), modifier = Modifier.size(16.dp) @@ -3057,12 +3133,20 @@ fun RequestsSection( isDarkTheme: Boolean, onClick: () -> Unit ) { - val textColor = remember(isDarkTheme) { if (isDarkTheme) Color.White else Color.Black } - val secondaryTextColor = - remember(isDarkTheme) { if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666) } + // Telegram archived chats uses muted colors: + // Title: #525252 (light) vs regular #222222 + // Message: #919191 (light) + // Badge: always grey #c6c9cc (light) + // Avatar bg: #B8C2CC (light) / #3A3A3C (dark) + val titleColor = remember(isDarkTheme) { + if (isDarkTheme) Color(0xFFAAAAAA) else Color(0xFF525252) + } + val subtitleColor = + remember(isDarkTheme) { if (isDarkTheme) Color(0xFF6E6E6E) else Color(0xFF919191) } val iconBgColor = - remember(isDarkTheme) { if (isDarkTheme) Color(0xFF3A3A3C) else Color(0xFFC7C7CC) } - val accentColor = if (isDarkTheme) PrimaryBlueDark else PrimaryBlue + remember(isDarkTheme) { if (isDarkTheme) Color(0xFF3A3A3C) else Color(0xFFB8C2CC) } + val badgeColor = + remember(isDarkTheme) { if (isDarkTheme) Color(0xFF4E4E4E) else Color(0xFFC6C9CC) } // Последний запрос — показываем имя отправителя как subtitle val lastRequest = remember(requests) { requests.firstOrNull() } @@ -3096,7 +3180,7 @@ fun RequestsSection( contentAlignment = Alignment.Center ) { Icon( - imageVector = TablerIcons.MailForward, + painter = painterResource(id = R.drawable.archive_filled), contentDescription = null, tint = Color.White, modifier = Modifier.size(26.dp) @@ -3116,7 +3200,7 @@ fun RequestsSection( text = "Requests", fontWeight = FontWeight.SemiBold, fontSize = 16.sp, - color = textColor, + color = titleColor, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f) @@ -3130,7 +3214,7 @@ fun RequestsSection( Modifier .defaultMinSize(minWidth = 22.dp, minHeight = 22.dp) .clip(CircleShape) - .background(accentColor), + .background(badgeColor), contentAlignment = Alignment.Center ) { Text( @@ -3151,20 +3235,13 @@ fun RequestsSection( Text( text = subtitle, fontSize = 14.sp, - color = secondaryTextColor, + color = subtitleColor, maxLines = 1, overflow = TextOverflow.Ellipsis ) } } } - - // Разделитель как у обычных чатов - Divider( - color = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE8E8E8), - thickness = 0.5.dp, - modifier = Modifier.padding(start = 84.dp) - ) } } diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/ForwardChatPickerBottomSheet.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/ForwardChatPickerBottomSheet.kt index 14f2e31..dccf5ba 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/ForwardChatPickerBottomSheet.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/ForwardChatPickerBottomSheet.kt @@ -417,7 +417,7 @@ private fun ForwardDialogItem( .size(24.dp) .clip(CircleShape) .background( - if (isSelected) Color(0xFF4CD964) + if (isSelected) PrimaryBlue else if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE0E0E0) ), diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/RequestsListScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/RequestsListScreen.kt index 273c22d..3bdc6de 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/RequestsListScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/RequestsListScreen.kt @@ -22,8 +22,9 @@ import androidx.compose.ui.unit.sp import com.rosetta.messenger.network.SearchUser import com.rosetta.messenger.repository.AvatarRepository import com.rosetta.messenger.ui.onboarding.PrimaryBlue +import com.rosetta.messenger.ui.icons.TelegramIcons import compose.icons.TablerIcons -import compose.icons.tablericons.ChevronLeft +import compose.icons.tablericons.* import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/SearchScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/SearchScreen.kt index c7ecc66..a5fd0e6 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/SearchScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/SearchScreen.kt @@ -11,9 +11,9 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import com.rosetta.messenger.ui.icons.TelegramIcons import compose.icons.TablerIcons -import compose.icons.tablericons.ArrowLeft -import compose.icons.tablericons.X +import compose.icons.tablericons.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Verified import androidx.compose.material3.* @@ -61,6 +61,14 @@ fun SearchScreen( val context = LocalContext.current val view = LocalView.current val focusManager = LocalFocusManager.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as android.app.Activity).window + val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view) + insetsController.isAppearanceLightStatusBars = !isDarkTheme + window.statusBarColor = android.graphics.Color.TRANSPARENT + } + } // 🔥 Функция мгновенного закрытия клавиатуры val hideKeyboardInstantly: () -> Unit = { @@ -173,7 +181,7 @@ fun SearchScreen( } ) { Icon( - TablerIcons.ArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = textColor.copy(alpha = 0.6f) ) @@ -233,7 +241,7 @@ fun SearchScreen( ) { IconButton(onClick = { searchViewModel.clearSearchQuery() }) { Icon( - TablerIcons.X, + painter = TelegramIcons.Close, contentDescription = "Clear", tint = secondaryTextColor.copy(alpha = 0.6f) ) @@ -424,7 +432,7 @@ private fun RecentUserItem( // Remove button IconButton(onClick = onRemove, modifier = Modifier.size(40.dp)) { Icon( - TablerIcons.X, + painter = TelegramIcons.Close, contentDescription = "Remove", tint = secondaryTextColor.copy(alpha = 0.6f), modifier = Modifier.size(20.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/components/AttachmentComponents.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/components/AttachmentComponents.kt index 65bdbc5..cd34e02 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/components/AttachmentComponents.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/components/AttachmentComponents.kt @@ -57,8 +57,7 @@ import com.rosetta.messenger.ui.onboarding.PrimaryBlue import com.rosetta.messenger.utils.AttachmentFileManager import com.rosetta.messenger.utils.AvatarFileManager import com.vanniktech.blurhash.BlurHash -import compose.icons.TablerIcons -import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.first @@ -1174,7 +1173,7 @@ fun ImageAttachment( when (messageStatus) { MessageStatus.SENDING -> { Icon( - compose.icons.TablerIcons.Clock, + painter = TelegramIcons.Clock, contentDescription = null, tint = Color.White.copy(alpha = 0.7f), modifier = Modifier.size(14.dp) @@ -1182,7 +1181,7 @@ fun ImageAttachment( } MessageStatus.SENT -> { Icon( - compose.icons.TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = null, tint = Color.White.copy(alpha = 0.7f), modifier = Modifier.size(14.dp) @@ -1190,7 +1189,7 @@ fun ImageAttachment( } MessageStatus.DELIVERED -> { Icon( - compose.icons.TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = null, tint = Color.White.copy(alpha = 0.7f), modifier = Modifier.size(14.dp) @@ -1198,7 +1197,7 @@ fun ImageAttachment( } MessageStatus.READ -> { Icon( - compose.icons.TablerIcons.Checks, + painter = TelegramIcons.Done, contentDescription = null, tint = Color.White, modifier = Modifier.size(14.dp) @@ -1546,7 +1545,7 @@ fun FileAttachment( when (messageStatus) { MessageStatus.SENDING -> { Icon( - compose.icons.TablerIcons.Clock, + painter = TelegramIcons.Clock, contentDescription = null, tint = Color.White.copy(alpha = 0.7f), modifier = Modifier.size(14.dp) @@ -1554,7 +1553,7 @@ fun FileAttachment( } MessageStatus.SENT -> { Icon( - compose.icons.TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = null, tint = Color.White.copy(alpha = 0.7f), modifier = Modifier.size(14.dp) @@ -1562,7 +1561,7 @@ fun FileAttachment( } MessageStatus.DELIVERED, MessageStatus.READ -> { Icon( - compose.icons.TablerIcons.Checks, + painter = TelegramIcons.Done, contentDescription = null, tint = if (messageStatus == MessageStatus.READ) { @@ -1934,7 +1933,7 @@ fun AvatarAttachment( when (messageStatus) { MessageStatus.SENDING -> { Icon( - compose.icons.TablerIcons.Clock, + painter = TelegramIcons.Clock, contentDescription = "Sending", tint = Color.White.copy(alpha = 0.6f), modifier = Modifier.size(14.dp) @@ -1942,7 +1941,7 @@ fun AvatarAttachment( } MessageStatus.SENT -> { Icon( - compose.icons.TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = "Sent", tint = Color.White.copy(alpha = 0.6f), modifier = Modifier.size(14.dp) @@ -1950,7 +1949,7 @@ fun AvatarAttachment( } MessageStatus.DELIVERED -> { Icon( - compose.icons.TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = "Delivered", tint = Color.White.copy(alpha = 0.6f), modifier = Modifier.size(14.dp) @@ -1958,7 +1957,7 @@ fun AvatarAttachment( } MessageStatus.READ -> { Icon( - compose.icons.TablerIcons.Checks, + painter = TelegramIcons.Done, contentDescription = "Read", tint = Color.White, modifier = Modifier.size(14.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/components/ChatDetailComponents.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/components/ChatDetailComponents.kt index d39d40c..2cf1e8e 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/components/ChatDetailComponents.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/components/ChatDetailComponents.kt @@ -50,6 +50,8 @@ import com.rosetta.messenger.utils.AttachmentFileManager import com.vanniktech.blurhash.BlurHash import compose.icons.TablerIcons import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons +import androidx.compose.ui.graphics.painter.Painter import java.text.SimpleDateFormat import java.util.* import kotlin.math.abs @@ -392,7 +394,7 @@ fun MessageBubble( contentAlignment = Alignment.Center ) { Icon( - TablerIcons.CornerUpLeft, + painter = TelegramIcons.Reply, contentDescription = "Reply", tint = if (swipeProgress >= 1f) Color.White @@ -449,11 +451,11 @@ fun MessageBubble( Modifier.padding(start = 12.dp, end = 4.dp) .size(24.dp) .clip(CircleShape) - .background(Color(0xFF4CD964)), + .background(PrimaryBlue), contentAlignment = Alignment.Center ) { Icon( - TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = "Selected", tint = Color.White, modifier = Modifier.size(16.dp) @@ -1026,28 +1028,33 @@ fun AnimatedMessageStatus( ) { currentStatus -> val iconSize = with(LocalDensity.current) { 14.sp.toDp() } - Icon( - imageVector = - when (currentStatus) { - MessageStatus.SENDING -> TablerIcons.Clock - MessageStatus.SENT -> TablerIcons.Check - MessageStatus.DELIVERED -> TablerIcons.Check - MessageStatus.READ -> TablerIcons.Checks - MessageStatus.ERROR -> TablerIcons.AlertCircle - }, - contentDescription = null, - tint = animatedColor, - modifier = - Modifier.size(iconSize) - .scale(scale) - .then( - if (currentStatus == MessageStatus.ERROR) { - Modifier.clickable { - showErrorMenu = true - } - } else Modifier - ) - ) + if (currentStatus == MessageStatus.ERROR) { + Icon( + imageVector = TablerIcons.AlertCircle, + contentDescription = null, + tint = animatedColor, + modifier = + Modifier.size(iconSize) + .scale(scale) + .clickable { + showErrorMenu = true + } + ) + } else { + Icon( + painter = + when (currentStatus) { + MessageStatus.SENDING -> TelegramIcons.Clock + MessageStatus.SENT -> TelegramIcons.Done + MessageStatus.DELIVERED -> TelegramIcons.Done + MessageStatus.READ -> TelegramIcons.Done + else -> TelegramIcons.Clock + }, + contentDescription = null, + tint = animatedColor, + modifier = Modifier.size(iconSize).scale(scale) + ) + } } DropdownMenu( @@ -1062,7 +1069,7 @@ fun AnimatedMessageStatus( }, leadingIcon = { Icon( - TablerIcons.Refresh, + painter = TelegramIcons.Retry, contentDescription = null, modifier = Modifier.size(18.dp) ) @@ -1076,7 +1083,7 @@ fun AnimatedMessageStatus( }, leadingIcon = { Icon( - TablerIcons.Trash, + painter = TelegramIcons.Delete, contentDescription = null, tint = Color(0xFFE53935), modifier = Modifier.size(18.dp) @@ -1370,7 +1377,7 @@ fun ReplyBubble( contentAlignment = Alignment.Center ) { Icon( - TablerIcons.Photo, + painter = TelegramIcons.Photos, contentDescription = null, tint = Color.White.copy(alpha = 0.7f), modifier = Modifier.size(28.dp) @@ -1631,7 +1638,7 @@ private fun ForwardedImagePreview( } else { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Icon( - TablerIcons.Photo, + painter = TelegramIcons.Photos, contentDescription = null, tint = Color.White.copy(alpha = 0.7f), modifier = Modifier.size(28.dp) @@ -1721,85 +1728,86 @@ fun KebabMenu( onDeleteClick: () -> Unit, onLogsClick: () -> Unit = {} ) { - val dividerColor = - if (isDarkTheme) Color.White.copy(alpha = 0.1f) else Color.Black.copy(alpha = 0.08f) + val menuBgColor = if (isDarkTheme) Color(0xFF272829) else Color.White + val textColor = if (isDarkTheme) Color.White else Color(0xFF222222) + val iconColor = if (isDarkTheme) Color.White.copy(alpha = 0.47f) else Color(0xFF676B70) + val dividerColor = if (isDarkTheme) Color(0xFF1C1D1F) else Color(0xFFF5F5F5) - DropdownMenu( - expanded = expanded, - onDismissRequest = onDismiss, - modifier = Modifier.width(220.dp), - properties = - PopupProperties( - focusable = true, - dismissOnBackPress = true, - dismissOnClickOutside = true - ) + MaterialTheme( + colorScheme = MaterialTheme.colorScheme.copy( + surface = menuBgColor, + onSurface = textColor + ) ) { - if (!isSavedMessages) { - KebabMenuItem( - icon = if (isBlocked) TablerIcons.CircleCheck else TablerIcons.Ban, - text = if (isBlocked) "Unblock User" else "Block User", - onClick = { if (isBlocked) onUnblockClick() else onBlockClick() }, - tintColor = PrimaryBlue, - textColor = if (isDarkTheme) Color.White else Color.Black - ) + DropdownMenu( + expanded = expanded, + onDismissRequest = onDismiss, + modifier = Modifier + .defaultMinSize(minWidth = 196.dp) + .background(menuBgColor), + properties = + PopupProperties( + focusable = true, + dismissOnBackPress = true, + dismissOnClickOutside = true + ) + ) { + if (!isSavedMessages) { + KebabMenuItem( + icon = if (isBlocked) TelegramIcons.Done else TelegramIcons.Block, + text = if (isBlocked) "Unblock User" else "Block User", + onClick = { if (isBlocked) onUnblockClick() else onBlockClick() }, + tintColor = iconColor, + textColor = textColor + ) + } - Box( - modifier = - Modifier.fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 4.dp) - .height(0.5.dp) - .background(dividerColor) + // Delete chat + KebabMenuItem( + icon = TelegramIcons.Delete, + text = "Delete Chat", + onClick = onDeleteClick, + tintColor = Color(0xFFFF3B30), + textColor = Color(0xFFFF3B30) ) } - - // Delete chat - KebabMenuItem( - icon = TablerIcons.Trash, - text = "Delete Chat", - onClick = onDeleteClick, - tintColor = Color(0xFFFF3B30), - textColor = Color(0xFFFF3B30) - ) } } @Composable private fun KebabMenuItem( - icon: ImageVector, + icon: Painter, text: String, onClick: () -> Unit, tintColor: Color, textColor: Color ) { - val interactionSource = remember { MutableInteractionSource() } - - DropdownMenuItem( - text = { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth() - ) { - Icon( - imageVector = icon, - contentDescription = null, - tint = tintColor, - modifier = Modifier.size(24.dp) - ) - Spacer(modifier = Modifier.width(14.dp)) - Text( - text = text, - color = textColor, - fontSize = 16.sp, - fontWeight = FontWeight.Medium - ) - } - }, - onClick = onClick, - modifier = Modifier.fillMaxWidth().padding(horizontal = 4.dp), - interactionSource = interactionSource, - contentPadding = PaddingValues(horizontal = 12.dp, vertical = 12.dp) - ) + // Telegram-style: 48dp height, 18dp horizontal padding + Box( + modifier = Modifier + .fillMaxWidth() + .defaultMinSize(minWidth = 196.dp, minHeight = 48.dp) + .clickable(onClick = onClick) + .padding(horizontal = 18.dp), + contentAlignment = Alignment.CenterStart + ) { + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + painter = icon, + contentDescription = null, + tint = tintColor, + modifier = Modifier.size(24.dp) + ) + Spacer(modifier = Modifier.width(19.dp)) + Text( + text = text, + color = textColor, + fontSize = 16.sp + ) + } + } } /** 🖼️ Превью изображения для reply в input bar (как в Telegram) */ @@ -1949,7 +1957,7 @@ fun ReplyImagePreview( contentAlignment = Alignment.Center ) { Icon( - TablerIcons.Photo, + painter = TelegramIcons.Photos, contentDescription = null, tint = Color.White.copy(alpha = 0.7f), modifier = Modifier.size(20.dp) @@ -1958,7 +1966,7 @@ fun ReplyImagePreview( } } } -/** Profile photo menu for avatar */ +/** Profile photo menu for avatar — Telegram style */ @Composable fun ProfilePhotoMenu( expanded: Boolean, @@ -1968,45 +1976,48 @@ fun ProfilePhotoMenu( onDeletePhotoClick: (() -> Unit)? = null, hasAvatar: Boolean = false ) { - val dividerColor = - if (isDarkTheme) Color.White.copy(alpha = 0.1f) else Color.Black.copy(alpha = 0.08f) + // Telegram popup colors + val menuBgColor = if (isDarkTheme) Color(0xFF272829) else Color.White + val textColor = if (isDarkTheme) Color.White else Color(0xFF222222) + val iconColor = if (isDarkTheme) Color.White.copy(alpha = 0.47f) else Color(0xFF676B70) + val dividerColor = if (isDarkTheme) Color(0xFF1C1D1F) else Color(0xFFF5F5F5) - DropdownMenu( - expanded = expanded, - onDismissRequest = onDismiss, - modifier = Modifier.width(220.dp), - properties = - PopupProperties( - focusable = true, - dismissOnBackPress = true, - dismissOnClickOutside = true - ) - ) { - ProfilePhotoMenuItem( - icon = TablerIcons.CameraPlus, - text = "Set Profile Photo", - onClick = onSetPhotoClick, - tintColor = if (isDarkTheme) Color.White else Color.Black, - textColor = if (isDarkTheme) Color.White else Color.Black + MaterialTheme( + colorScheme = MaterialTheme.colorScheme.copy( + surface = menuBgColor, + onSurface = textColor ) - - // Показываем Delete только если есть аватар - if (hasAvatar && onDeletePhotoClick != null) { - Box( - modifier = - Modifier.fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 4.dp) - .height(0.5.dp) - .background(dividerColor) - ) - + ) { + DropdownMenu( + expanded = expanded, + onDismissRequest = onDismiss, + modifier = Modifier + .defaultMinSize(minWidth = 196.dp) + .background(menuBgColor), + properties = + PopupProperties( + focusable = true, + dismissOnBackPress = true, + dismissOnClickOutside = true + ) + ) { ProfilePhotoMenuItem( - icon = TablerIcons.Trash, - text = "Delete Photo", - onClick = onDeletePhotoClick, - tintColor = Color(0xFFFF3B30), - textColor = Color(0xFFFF3B30) + icon = TelegramIcons.AddPhoto, + text = if (hasAvatar) "Set Profile Photo" else "Add Photo", + onClick = onSetPhotoClick, + tintColor = iconColor, + textColor = textColor ) + + if (hasAvatar && onDeletePhotoClick != null) { + ProfilePhotoMenuItem( + icon = TelegramIcons.Delete, + text = "Delete Photo", + onClick = onDeletePhotoClick, + tintColor = Color(0xFFFF3B30), + textColor = Color(0xFFFF3B30) + ) + } } } } @@ -2021,80 +2032,81 @@ fun OtherProfileMenu( onBlockClick: () -> Unit, onClearChatClick: () -> Unit ) { - val dividerColor = - if (isDarkTheme) Color.White.copy(alpha = 0.1f) else Color.Black.copy(alpha = 0.08f) + val menuBgColor = if (isDarkTheme) Color(0xFF272829) else Color.White + val textColor = if (isDarkTheme) Color.White else Color(0xFF222222) + val iconColor = if (isDarkTheme) Color.White.copy(alpha = 0.47f) else Color(0xFF676B70) + val dividerColor = if (isDarkTheme) Color(0xFF1C1D1F) else Color(0xFFF5F5F5) - DropdownMenu( - expanded = expanded, - onDismissRequest = onDismiss, - modifier = Modifier.width(220.dp), - properties = - PopupProperties( - focusable = true, - dismissOnBackPress = true, - dismissOnClickOutside = true - ) + MaterialTheme( + colorScheme = MaterialTheme.colorScheme.copy( + surface = menuBgColor, + onSurface = textColor + ) ) { - ProfilePhotoMenuItem( - icon = if (isBlocked) TablerIcons.CircleCheck else TablerIcons.Ban, - text = if (isBlocked) "Unblock User" else "Block User", - onClick = onBlockClick, - tintColor = PrimaryBlue, - textColor = if (isDarkTheme) Color.White else Color.Black - ) + DropdownMenu( + expanded = expanded, + onDismissRequest = onDismiss, + modifier = Modifier + .defaultMinSize(minWidth = 196.dp) + .background(menuBgColor), + properties = + PopupProperties( + focusable = true, + dismissOnBackPress = true, + dismissOnClickOutside = true + ) + ) { + ProfilePhotoMenuItem( + icon = if (isBlocked) TelegramIcons.Done else TelegramIcons.Block, + text = if (isBlocked) "Unblock User" else "Block User", + onClick = onBlockClick, + tintColor = iconColor, + textColor = textColor + ) - Box( - modifier = - Modifier.fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 4.dp) - .height(0.5.dp) - .background(dividerColor) - ) - - ProfilePhotoMenuItem( - icon = TablerIcons.Trash, - text = "Clear Chat History", - onClick = onClearChatClick, - tintColor = Color(0xFFFF3B30), - textColor = Color(0xFFFF3B30) - ) + ProfilePhotoMenuItem( + icon = TelegramIcons.Delete, + text = "Clear Chat History", + onClick = onClearChatClick, + tintColor = Color(0xFFFF3B30), + textColor = Color(0xFFFF3B30) + ) + } } } @Composable private fun ProfilePhotoMenuItem( - icon: ImageVector, + icon: Painter, text: String, onClick: () -> Unit, tintColor: Color, textColor: Color ) { - val interactionSource = remember { MutableInteractionSource() } - - DropdownMenuItem( - text = { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth() - ) { - Icon( - imageVector = icon, - contentDescription = null, - tint = tintColor, - modifier = Modifier.size(24.dp) - ) - Spacer(modifier = Modifier.width(14.dp)) - Text( - text = text, - color = textColor, - fontSize = 16.sp, - fontWeight = FontWeight.Medium - ) - } - }, - onClick = onClick, - modifier = Modifier.fillMaxWidth().padding(horizontal = 4.dp), - interactionSource = interactionSource, - contentPadding = PaddingValues(horizontal = 12.dp, vertical = 12.dp) - ) + // Telegram: 48dp height, 18dp horizontal padding, 16sp text, icon→text gap 43dp + Box( + modifier = Modifier + .fillMaxWidth() + .defaultMinSize(minWidth = 196.dp, minHeight = 48.dp) + .clickable(onClick = onClick) + .padding(horizontal = 18.dp), + contentAlignment = Alignment.CenterStart + ) { + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + painter = icon, + contentDescription = null, + tint = tintColor, + modifier = Modifier.size(24.dp) + ) + Spacer(modifier = Modifier.width(19.dp)) + Text( + text = text, + color = textColor, + fontSize = 16.sp + ) + } + } } diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/components/DebugLogsBottomSheet.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/components/DebugLogsBottomSheet.kt index caafc91..596c50a 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/components/DebugLogsBottomSheet.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/components/DebugLogsBottomSheet.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.unit.sp import com.rosetta.messenger.ui.onboarding.PrimaryBlue import compose.icons.TablerIcons import compose.icons.tablericons.Bug -import compose.icons.tablericons.Trash +import com.rosetta.messenger.ui.icons.TelegramIcons import kotlinx.coroutines.launch /** @@ -165,7 +165,7 @@ fun DebugLogsBottomSheet( Row { IconButton(onClick = onClearLogs) { Icon( - TablerIcons.Trash, + painter = TelegramIcons.Delete, contentDescription = "Clear logs", tint = secondaryTextColor.copy(alpha = 0.6f), modifier = Modifier.size(22.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/components/ImageEditorScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/components/ImageEditorScreen.kt index e12fe0f..53558d4 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/components/ImageEditorScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/components/ImageEditorScreen.kt @@ -66,6 +66,7 @@ import com.rosetta.messenger.ui.utils.SystemBarsStyleUtils import com.yalantis.ucrop.UCrop import compose.icons.TablerIcons import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import ja.burhanrashid52.photoeditor.PhotoEditor import ja.burhanrashid52.photoeditor.PhotoEditorView import ja.burhanrashid52.photoeditor.SaveSettings @@ -472,7 +473,7 @@ fun ImageEditorScreen( modifier = Modifier.align(Alignment.CenterStart) ) { Icon( - TablerIcons.X, + painter = TelegramIcons.Close, contentDescription = "Close", tint = Color.White, modifier = Modifier.size(28.dp) @@ -1102,7 +1103,7 @@ private fun TelegramCaptionBar( modifier = Modifier.size(32.dp) ) { Icon( - if (showEmojiPicker) TablerIcons.Keyboard else TablerIcons.MoodSmile, + painter = if (showEmojiPicker) TelegramIcons.Keyboard else TelegramIcons.Smile, contentDescription = if (showEmojiPicker) "Keyboard" else "Emoji", tint = Color.White.copy(alpha = 0.7f), modifier = Modifier.size(26.dp) @@ -1699,7 +1700,7 @@ fun MultiImageEditorScreen( modifier = Modifier.align(Alignment.CenterStart) ) { Icon( - TablerIcons.X, + painter = TelegramIcons.Close, contentDescription = "Close", tint = Color.White, modifier = Modifier.size(28.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/components/MediaPickerBottomSheet.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/components/MediaPickerBottomSheet.kt index 55167d7..ac22315 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/components/MediaPickerBottomSheet.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/components/MediaPickerBottomSheet.kt @@ -64,6 +64,7 @@ import coil.compose.AsyncImage import coil.request.ImageRequest import compose.icons.TablerIcons import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import com.rosetta.messenger.ui.onboarding.PrimaryBlue import com.rosetta.messenger.ui.components.AppleEmojiTextField import com.rosetta.messenger.ui.components.KeyboardHeightProvider @@ -597,7 +598,7 @@ fun MediaPickerBottomSheet( horizontalAlignment = Alignment.CenterHorizontally ) { Icon( - TablerIcons.Photo, + painter = TelegramIcons.Photos, contentDescription = null, tint = secondaryTextColor, modifier = Modifier.size(64.dp) @@ -862,7 +863,7 @@ private fun MediaPickerHeader( contentPadding = PaddingValues(horizontal = 20.dp, vertical = 8.dp) ) { Icon( - TablerIcons.Send, + painter = TelegramIcons.Send, contentDescription = "Send", modifier = Modifier.size(18.dp), tint = Color.White @@ -897,7 +898,7 @@ private fun QuickActionsRow( ) { // Camera button QuickActionButton( - icon = TablerIcons.Camera, + icon = TelegramIcons.Camera, label = "Camera", backgroundColor = PrimaryBlue, iconColor = Color.White, @@ -907,7 +908,7 @@ private fun QuickActionsRow( // Avatar button QuickActionButton( - icon = TablerIcons.User, + icon = TelegramIcons.Contact, label = "Avatar", backgroundColor = buttonColor, iconColor = iconColor, @@ -917,7 +918,7 @@ private fun QuickActionsRow( // File button QuickActionButton( - icon = TablerIcons.File, + icon = TelegramIcons.File, label = "File", backgroundColor = buttonColor, iconColor = iconColor, @@ -929,7 +930,7 @@ private fun QuickActionsRow( @Composable private fun QuickActionButton( - icon: androidx.compose.ui.graphics.vector.ImageVector, + icon: androidx.compose.ui.graphics.painter.Painter, label: String, backgroundColor: Color, iconColor: Color, @@ -969,7 +970,7 @@ private fun QuickActionButton( contentAlignment = Alignment.Center ) { Icon( - imageVector = icon, + painter = icon, contentDescription = label, tint = iconColor, modifier = Modifier.size(24.dp) @@ -1125,7 +1126,7 @@ private fun CameraGridItem( contentAlignment = Alignment.Center ) { Icon( - imageVector = TablerIcons.Camera, + painter = TelegramIcons.Camera, contentDescription = "Camera", tint = Color.White, modifier = Modifier @@ -1143,7 +1144,7 @@ private fun CameraGridItem( verticalArrangement = Arrangement.Center ) { Icon( - imageVector = TablerIcons.Camera, + painter = TelegramIcons.Camera, contentDescription = "Camera", tint = PrimaryBlue, modifier = Modifier @@ -1262,7 +1263,7 @@ private fun MediaGridItem( ) { if (isSelected) { Icon( - imageVector = TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = null, tint = Color.White, modifier = Modifier.size(16.dp) @@ -1586,7 +1587,7 @@ fun PhotoPreviewWithCaptionScreen( modifier = Modifier.align(Alignment.CenterStart) ) { Icon( - TablerIcons.X, + painter = TelegramIcons.Close, contentDescription = "Close", tint = Color.White, modifier = Modifier.size(28.dp) @@ -1634,7 +1635,7 @@ fun PhotoPreviewWithCaptionScreen( label = "emojiIcon" ) { isEmoji -> Icon( - if (isEmoji) TablerIcons.Keyboard else TablerIcons.MoodSmile, + painter = if (isEmoji) TelegramIcons.Keyboard else TelegramIcons.Smile, contentDescription = if (isEmoji) "Keyboard" else "Emoji", tint = Color.White.copy(alpha = 0.7f), modifier = Modifier.size(26.dp) @@ -1676,7 +1677,7 @@ fun PhotoPreviewWithCaptionScreen( contentAlignment = Alignment.Center ) { Icon( - TablerIcons.Send, + painter = TelegramIcons.Send, contentDescription = "Send", tint = Color.White, modifier = Modifier diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt index 60ef793..a0d8c5a 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt @@ -10,8 +10,7 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.* -import compose.icons.TablerIcons -import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import androidx.compose.runtime.* import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment @@ -272,7 +271,7 @@ fun MessageInputBar( horizontalArrangement = Arrangement.Center ) { Icon( - TablerIcons.Ban, + painter = TelegramIcons.Block, contentDescription = null, tint = Color(0xFFFF6B6B), modifier = Modifier.size(20.dp) @@ -419,7 +418,7 @@ fun MessageInputBar( contentAlignment = Alignment.Center ) { Icon( - TablerIcons.X, + painter = TelegramIcons.Close, contentDescription = "Cancel", tint = if (isDarkTheme) Color.White.copy(alpha = 0.5f) else Color.Black.copy(alpha = 0.4f), @@ -442,7 +441,7 @@ fun MessageInputBar( modifier = Modifier.size(40.dp) ) { Icon( - TablerIcons.Paperclip, + painter = TelegramIcons.Attach, contentDescription = "Attach", tint = if (isDarkTheme) Color(0xFF8E8E93).copy(alpha = 0.6f) else Color(0xFF8E8E93).copy(alpha = 0.6f), @@ -485,8 +484,8 @@ fun MessageInputBar( modifier = Modifier.size(40.dp) ) { Icon( - if (showEmojiPicker) TablerIcons.Keyboard - else TablerIcons.MoodSmile, + painter = if (showEmojiPicker) TelegramIcons.Keyboard + else TelegramIcons.Smile, contentDescription = "Emoji", tint = if (isDarkTheme) Color(0xFF8E8E93).copy(alpha = 0.6f) else Color(0xFF8E8E93).copy(alpha = 0.6f), diff --git a/app/src/main/java/com/rosetta/messenger/ui/icons/TelegramIcons.kt b/app/src/main/java/com/rosetta/messenger/ui/icons/TelegramIcons.kt new file mode 100644 index 0000000..64f787a --- /dev/null +++ b/app/src/main/java/com/rosetta/messenger/ui/icons/TelegramIcons.kt @@ -0,0 +1,93 @@ +package com.rosetta.messenger.ui.icons + +import androidx.annotation.DrawableRes +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.res.painterResource +import com.rosetta.messenger.R + +/** + * Centralized Telegram icon provider. + * Maps to Telegram's native PNG drawable resources. + * Use with Icon(painter = TelegramIcons.ArrowBack, ...) + */ +object TelegramIcons { + + // ═══════════════════════════════════════════════════════════ + // 🧭 NAVIGATION + // ═══════════════════════════════════════════════════════════ + val ArrowBack: Painter @Composable get() = painterResource(R.drawable.msg_arrow_back) + val Close: Painter @Composable get() = painterResource(R.drawable.msg_close) + val ChevronDown: Painter @Composable get() = painterResource(R.drawable.ic_arrow_drop_down) + val ChevronRight: Painter @Composable get() = painterResource(R.drawable.msg_arrowright) + val More: Painter @Composable get() = painterResource(R.drawable.ic_ab_other) + + // ═══════════════════════════════════════════════════════════ + + // ═══════════════════════════════════════════════════════════ + val Done: Painter @Composable get() = painterResource(R.drawable.ic_ab_done) + val Add: Painter @Composable get() = painterResource(R.drawable.msg_add) + val Edit: Painter @Composable get() = painterResource(R.drawable.msg_edit) + val Delete: Painter @Composable get() = painterResource(R.drawable.msg_delete) + val Reply: Painter @Composable get() = painterResource(R.drawable.ic_ab_reply) + val Retry: Painter @Composable get() = painterResource(R.drawable.msg_retry) + val Send: Painter @Composable get() = painterResource(R.drawable.msg_send) + + // ═══════════════════════════════════════════════════════════ + // 🔔 NOTIFICATIONS + // ═══════════════════════════════════════════════════════════ + val Notifications: Painter @Composable get() = painterResource(R.drawable.msg_notifications) + val Mute: Painter @Composable get() = painterResource(R.drawable.msg_mute) + + // ═══════════════════════════════════════════════════════════ + // 📌 CHAT ACTIONS + // ═══════════════════════════════════════════════════════════ + val Pin: Painter @Composable get() = painterResource(R.drawable.msg_pin) + val Unpin: Painter @Composable get() = painterResource(R.drawable.msg_unpin) + val Block: Painter @Composable get() = painterResource(R.drawable.msg_block) + val Message: Painter @Composable get() = painterResource(R.drawable.msg_message) + + // ═══════════════════════════════════════════════════════════ + // 🔒 SECURITY + // ═══════════════════════════════════════════════════════════ + val Secret: Painter @Composable get() = painterResource(R.drawable.msg_secret) + val Unlock: Painter @Composable get() = painterResource(R.drawable.menu_unlock) + val Fingerprint: Painter @Composable get() = painterResource(R.drawable.fingerprint) + + // ═══════════════════════════════════════════════════════════ + // 📷 MEDIA + // ═══════════════════════════════════════════════════════════ + val Camera: Painter @Composable get() = painterResource(R.drawable.msg_camera) + val AddPhoto: Painter @Composable get() = painterResource(R.drawable.msg_addphoto) + val Photos: Painter @Composable get() = painterResource(R.drawable.msg_photos) + val File: Painter @Composable get() = painterResource(R.drawable.msg_sendfile) + val Attach: Painter @Composable get() = painterResource(R.drawable.input_attach) + + // ═══════════════════════════════════════════════════════════ + // 😊 INPUT + // ═══════════════════════════════════════════════════════════ + val Smile: Painter @Composable get() = painterResource(R.drawable.input_smile) + val Keyboard: Painter @Composable get() = painterResource(R.drawable.input_keyboard) + + // ═══════════════════════════════════════════════════════════ + // ⚙️ SETTINGS + // ═══════════════════════════════════════════════════════════ + val Palette: Painter @Composable get() = painterResource(R.drawable.msg_palette) + val Theme: Painter @Composable get() = painterResource(R.drawable.msg_theme) + val Customize: Painter @Composable get() = painterResource(R.drawable.msg_customize) + val Leave: Painter @Composable get() = painterResource(R.drawable.msg_leave) + + // ═══════════════════════════════════════════════════════════ + // 👤 CONTACTS + // ═══════════════════════════════════════════════════════════ + val Contact: Painter @Composable get() = painterResource(R.drawable.msg_contact) + val AddContact: Painter @Composable get() = painterResource(R.drawable.msg_addcontact) + + // ═══════════════════════════════════════════════════════════ + // ℹ️ STATUS & INFO + // ═══════════════════════════════════════════════════════════ + val Clock: Painter @Composable get() = painterResource(R.drawable.msg_autodelete) + val Warning: Painter @Composable get() = painterResource(R.drawable.msg_warning) + val Info: Painter @Composable get() = painterResource(R.drawable.msg_info) + val Views: Painter @Composable get() = painterResource(R.drawable.msg_views) +} diff --git a/app/src/main/java/com/rosetta/messenger/ui/settings/AppearanceScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/settings/AppearanceScreen.kt index 8755152..4ab277e 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/settings/AppearanceScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/settings/AppearanceScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material3.* import compose.icons.TablerIcons import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -28,6 +29,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalView import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @@ -55,6 +57,16 @@ fun AppearanceScreen( accountName: String = "", avatarRepository: AvatarRepository? = null ) { + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as android.app.Activity).window + val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view) + insetsController.isAppearanceLightStatusBars = !isDarkTheme + window.statusBarColor = android.graphics.Color.TRANSPARENT + } + } + val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF) val textColor = if (isDarkTheme) Color.White else Color.Black val secondaryTextColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666) @@ -101,7 +113,7 @@ fun AppearanceScreen( ) { IconButton(onClick = onBack) { Icon( - imageVector = TablerIcons.ArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = Color.White ) @@ -441,7 +453,7 @@ private fun ColorCircleItem( val borderColor by animateColorAsState( targetValue = if (isSelected) { - Color.White + if (isDarkTheme) Color.White else Color(0xFF222222) } else { Color.Transparent }, @@ -456,7 +468,7 @@ private fun ColorCircleItem( .clip(CircleShape) .border( width = if (isSelected) 2.5.dp else 0.5.dp, - color = if (isSelected) borderColor else Color.White.copy(alpha = 0.12f), + color = if (isSelected) borderColor else if (isDarkTheme) Color.White.copy(alpha = 0.12f) else Color.Black.copy(alpha = 0.12f), shape = CircleShape ) .clickable(onClick = onClick), @@ -509,7 +521,7 @@ private fun ColorCircleItem( contentAlignment = Alignment.Center ) { Icon( - imageVector = TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = "Selected", tint = Color.White, modifier = Modifier.size(18.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/settings/BiometricEnableScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/settings/BiometricEnableScreen.kt index 07e3a50..ca55f62 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/settings/BiometricEnableScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/settings/BiometricEnableScreen.kt @@ -30,6 +30,7 @@ import com.airbnb.lottie.compose.* import com.rosetta.messenger.ui.onboarding.PrimaryBlue import compose.icons.TablerIcons import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import kotlinx.coroutines.delay // Auth colors @@ -82,6 +83,14 @@ fun BiometricEnableScreen( val focusManager = LocalFocusManager.current val context = LocalContext.current val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as android.app.Activity).window + val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view) + insetsController.isAppearanceLightStatusBars = !isDarkTheme + window.statusBarColor = android.graphics.Color.TRANSPARENT + } + } // Function to hide keyboard fun hideKeyboard() { @@ -141,7 +150,7 @@ fun BiometricEnableScreen( ) { IconButton(onClick = onBack, enabled = !isLoading) { Icon( - imageVector = TablerIcons.ArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = textColor.copy(alpha = 0.6f) ) @@ -312,7 +321,7 @@ fun BiometricEnableScreen( verticalAlignment = Alignment.CenterVertically ) { Icon( - imageVector = TablerIcons.AlertCircle, + painter = TelegramIcons.Warning, contentDescription = null, tint = errorRed, modifier = Modifier.size(16.dp) @@ -377,7 +386,7 @@ fun BiometricEnableScreen( ) } else { Icon( - imageVector = TablerIcons.Fingerprint, + painter = TelegramIcons.Fingerprint, contentDescription = null, modifier = Modifier.size(22.dp) ) @@ -408,7 +417,7 @@ fun BiometricEnableScreen( verticalAlignment = Alignment.Top ) { Icon( - imageVector = TablerIcons.ShieldLock, + painter = TelegramIcons.Secret, contentDescription = null, tint = PrimaryBlue, modifier = Modifier.size(20.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/settings/OtherProfileScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/settings/OtherProfileScreen.kt index 7c56633..1b8a348 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/settings/OtherProfileScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/settings/OtherProfileScreen.kt @@ -32,8 +32,6 @@ import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.outlined.Block import androidx.compose.material3.* import androidx.compose.runtime.* @@ -43,6 +41,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.graphicsLayer @@ -62,6 +61,7 @@ import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.Velocity import androidx.compose.ui.unit.dp @@ -93,6 +93,7 @@ import com.rosetta.messenger.ui.components.metaball.ProfileMetaballEffect import com.rosetta.messenger.ui.onboarding.PrimaryBlue import com.rosetta.messenger.utils.AttachmentFileManager import com.rosetta.messenger.utils.AvatarFileManager +import com.rosetta.messenger.ui.icons.TelegramIcons import compose.icons.TablerIcons import compose.icons.tablericons.* import kotlinx.coroutines.CoroutineScope @@ -220,6 +221,10 @@ fun OtherProfileScreen( val chatsListViewModel: ChatsListViewModel = viewModel() val coroutineScope = rememberCoroutineScope() + // 🔕 Mute state + val preferencesManager = remember { com.rosetta.messenger.data.PreferencesManager(context) } + var notificationsEnabled by remember { mutableStateOf(true) } + // 🔥 Загружаем статус блокировки при открытии экрана LaunchedEffect(user.publicKey) { isBlocked = chatsListViewModel.isUserBlocked(user.publicKey) } @@ -244,6 +249,14 @@ fun OtherProfileScreen( remember(currentUserPublicKey) { currentUserPublicKey.trim() } val activeAccountPrivateKey = remember(currentUserPrivateKey) { currentUserPrivateKey.trim() } + + // 🔕 Load mute state from preferences + LaunchedEffect(activeAccountPublicKey, user.publicKey) { + if (activeAccountPublicKey.isNotBlank()) { + notificationsEnabled = !preferencesManager.isChatMuted(activeAccountPublicKey, user.publicKey) + } + } + val dialogKey = remember(activeAccountPublicKey, user.publicKey) { if (activeAccountPublicKey.isBlank()) { @@ -522,14 +535,14 @@ fun OtherProfileScreen( ) ) { item { - Spacer(modifier = Modifier.height(16.dp)) - - Spacer(modifier = Modifier.height(6.dp)) - // ═══════════════════════════════════════════════════════════ - // 📋 ACCOUNT SECTION + // 📋 INFORMATION SECTION — первый элемент // ═══════════════════════════════════════════════════════════ - TelegramSectionTitle(title = "Account", isDarkTheme = isDarkTheme) + TelegramSectionTitle( + title = "Information", + isDarkTheme = isDarkTheme, + color = PrimaryBlue + ) if (user.username.isNotBlank()) { TelegramCopyField( @@ -538,6 +551,12 @@ fun OtherProfileScreen( label = "Username", isDarkTheme = isDarkTheme ) + + Divider( + color = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE0E0E0), + thickness = 0.5.dp, + modifier = Modifier.padding(start = 16.dp) + ) } TelegramCopyField( @@ -547,11 +566,21 @@ fun OtherProfileScreen( isDarkTheme = isDarkTheme ) - Spacer(modifier = Modifier.height(12.dp)) + // ═══════════════════════════════════════════════════════════ + // Разделитель секций + // ═══════════════════════════════════════════════════════════ + Box( + modifier = Modifier + .fillMaxWidth() + .height(8.dp) + .background(if (isDarkTheme) Color(0xFF0F0F0F) else Color(0xFFF0F0F0)) + ) // ═══════════════════════════════════════════════════════════ // ✉️ WRITE MESSAGE BUTTON // ═══════════════════════════════════════════════════════════ + Spacer(modifier = Modifier.height(12.dp)) + Box( modifier = Modifier .fillMaxWidth() @@ -573,7 +602,7 @@ fun OtherProfileScreen( ) ) { Icon( - TablerIcons.MessageCircle2, + painter = TelegramIcons.Message, contentDescription = null, modifier = Modifier.size(20.dp), tint = Color.White @@ -588,13 +617,32 @@ fun OtherProfileScreen( } } - Spacer(modifier = Modifier.height(16.dp)) + Spacer(modifier = Modifier.height(12.dp)) // ═══════════════════════════════════════════════════════════ - // 📚 SHARED CONTENT + // 🔔 NOTIFICATIONS SECTION // ═══════════════════════════════════════════════════════════ - TelegramSectionTitle(title = "Shared", isDarkTheme = isDarkTheme) + TelegramToggleItem( + icon = if (notificationsEnabled) TelegramIcons.Notifications else TelegramIcons.Mute, + title = "Notifications", + subtitle = if (notificationsEnabled) "On" else "Off", + isEnabled = notificationsEnabled, + onToggle = { + notificationsEnabled = !notificationsEnabled + coroutineScope.launch { + preferencesManager.setChatMuted( + activeAccountPublicKey, + user.publicKey, + !notificationsEnabled + ) + } + }, + isDarkTheme = isDarkTheme + ) + // ═══════════════════════════════════════════════════════════ + // 📚 SHARED CONTENT (без разделителя — сразу табы) + // ═══════════════════════════════════════════════════════════ OtherProfileSharedTabs( selectedTab = selectedTab, onTabSelected = { tab -> @@ -1202,7 +1250,7 @@ private fun OtherProfileActionButtons( horizontalArrangement = Arrangement.spacedBy(12.dp) ) { OtherProfileActionButton( - icon = TablerIcons.MessageCircle2, + icon = TelegramIcons.Message, title = "Message", subtitle = "Open chat", accent = PrimaryBlue, @@ -1211,7 +1259,7 @@ private fun OtherProfileActionButtons( onClick = onMessageClick ) OtherProfileActionButton( - icon = if (isMuted) TablerIcons.BellOff else TablerIcons.BellRinging2, + icon = if (isMuted) TelegramIcons.Mute else TelegramIcons.Notifications, title = if (isMuted) "Muted" else "Mute", subtitle = if (isMuted) "Tap to unmute" else "Silence notifications", accent = @@ -1229,7 +1277,7 @@ private fun OtherProfileActionButtons( @Composable private fun OtherProfileActionButton( - icon: ImageVector, + icon: Painter, title: String, subtitle: String, accent: Color, @@ -1260,7 +1308,7 @@ private fun OtherProfileActionButton( contentAlignment = Alignment.Center ) { Icon( - imageVector = icon, + painter = icon, contentDescription = title, tint = accent, modifier = Modifier.size(19.dp) @@ -1504,7 +1552,7 @@ private fun OtherProfileFileList( contentAlignment = Alignment.Center ) { Icon( - imageVector = TablerIcons.File, + painter = TelegramIcons.File, contentDescription = null, tint = PrimaryBlue, modifier = Modifier.size(18.dp) @@ -1661,8 +1709,11 @@ private fun CollapsingOtherProfileHeader( val avatarFontSize = androidx.compose.ui.unit.lerp(40.sp, 12.sp, collapseProgress) // Text animation - always centered - val textDefaultY = expandedHeight - 48.dp - val textCollapsedY = statusBarHeight + COLLAPSED_HEADER_HEIGHT_OTHER / 2 + val textDefaultY = expandedHeight - 70.dp + // Collapsed: center text block vertically in collapsed header + // Text block is ~42dp tall (name 18sp ~22dp + 2dp spacer + online 13sp ~18dp) + val textBlockHeight = 42.dp + val textCollapsedY = statusBarHeight + (COLLAPSED_HEADER_HEIGHT_OTHER - textBlockHeight) / 2 val textY = androidx.compose.ui.unit.lerp(textDefaultY, textCollapsedY, collapseProgress) val nameFontSize = androidx.compose.ui.unit.lerp(24.sp, 18.sp, collapseProgress) @@ -1673,7 +1724,19 @@ private fun CollapsingOtherProfileHeader( // ═══════════════════════════════════════════════════════════ val textColor = Color.White + // ═══════════════════════════════════════════════════════════ + // 🔙 BUTTONS Y - At top when expanded, centered when collapsed + // ═══════════════════════════════════════════════════════════ + val buttonsExpandedY = statusBarHeight + 8.dp + val buttonsCollapsedY = statusBarHeight + (COLLAPSED_HEADER_HEIGHT_OTHER - 48.dp) / 2 + val buttonsY = androidx.compose.ui.unit.lerp(buttonsExpandedY, buttonsCollapsedY, collapseProgress) + Box(modifier = Modifier.fillMaxWidth().height(headerHeight).clipToBounds()) { + // Solid opaque background floor — prevents content from bleeding through + Box(modifier = Modifier.matchParentSize().background( + if (isDarkTheme) Color(0xFF1C1C1E) else Color(0xFFEFEFF4) + )) + // Expansion fraction — computed early so blur can fade during expansion val expandFractionEarly = expansionProgress.coerceIn(0f, 1f) val blurAlpha = (1f - expandFractionEarly * 2.5f).coerceIn(0f, 1f) @@ -1695,6 +1758,28 @@ private fun CollapsingOtherProfileHeader( } } + // ═══════════════════════════════════════════════════════════ + // 🌅 BOTTOM GRADIENT — плавно исчезает когда аватарка раскрывается + // ═══════════════════════════════════════════════════════════ + val gradientAlpha = (1f - expandFractionEarly * 1.2f).coerceIn(0f, 1f) + if (gradientAlpha > 0.01f) { + Box( + modifier = Modifier + .fillMaxWidth() + .height(80.dp) + .align(Alignment.BottomCenter) + .graphicsLayer { alpha = gradientAlpha } + .background( + Brush.verticalGradient( + colors = listOf( + Color.Transparent, + Color.Black.copy(alpha = 0.35f) + ) + ) + ) + ) + } + // ═══════════════════════════════════════════════════════════ // 👤 AVATAR — Telegram-style expansion on pull-down // При скролле вверх: metaball merge с Dynamic Island @@ -1795,19 +1880,56 @@ private fun CollapsingOtherProfileHeader( } } + // Gradient overlays when avatar is expanded + if (expansionAvatarAlpha > 0.01f) { + // Top gradient + Box( + modifier = Modifier + .fillMaxWidth() + .height(120.dp) + .align(Alignment.TopCenter) + .graphicsLayer { alpha = expandFraction.coerceIn(0f, 1f) } + .background( + Brush.verticalGradient( + colors = listOf( + Color.Black.copy(alpha = 0.6f), + Color.Transparent + ) + ) + ) + ) + // Bottom gradient + Box( + modifier = Modifier + .fillMaxWidth() + .height(120.dp) + .align(Alignment.BottomCenter) + .graphicsLayer { alpha = expandFraction.coerceIn(0f, 1f) } + .background( + Brush.verticalGradient( + colors = listOf( + Color.Transparent, + Color.Black.copy(alpha = 0.6f) + ) + ) + ) + ) + } + // ═══════════════════════════════════════════════════════════ - // 🔙 BACK BUTTON + // 🔙 BACK BUTTON - At top when expanded, centered when collapsed // ═══════════════════════════════════════════════════════════ Box( modifier = - Modifier.padding(top = statusBarHeight) - .padding(start = 4.dp, top = 4.dp) + Modifier + .align(Alignment.TopStart) + .offset(x = 4.dp, y = buttonsY) .size(48.dp), contentAlignment = Alignment.Center ) { IconButton(onClick = onBack, modifier = Modifier.size(48.dp)) { Icon( - imageVector = Icons.Filled.ArrowBack, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = Color.White, modifier = Modifier.size(24.dp) @@ -1816,19 +1938,17 @@ private fun CollapsingOtherProfileHeader( } // ═══════════════════════════════════════════════════════════ - // ⋮ MENU BUTTON (top right corner) + // ⋮ MENU BUTTON - At top when expanded, centered when collapsed // ═══════════════════════════════════════════════════════════ Box( modifier = Modifier.align(Alignment.TopEnd) - .padding(top = statusBarHeight) - .padding(end = 4.dp, top = 4.dp) - .size(48.dp), + .offset(x = -4.dp, y = buttonsY), contentAlignment = Alignment.Center ) { IconButton(onClick = { onAvatarMenuChange(true) }, modifier = Modifier.size(48.dp)) { Icon( - imageVector = Icons.Default.MoreVert, + painter = TelegramIcons.More, contentDescription = "Profile menu", tint = Color.White, modifier = Modifier.size(24.dp) @@ -1857,17 +1977,7 @@ private fun CollapsingOtherProfileHeader( // ═══════════════════════════════════════════════════════════ Column( modifier = - Modifier.align(Alignment.TopCenter).offset(y = textY).graphicsLayer { - val centerOffsetY = - with(density) { - androidx.compose - .ui - .unit - .lerp(24.dp, 18.dp, collapseProgress) - .toPx() - } - translationY = -centerOffsetY - }, + Modifier.align(Alignment.TopCenter).offset(y = textY), horizontalAlignment = Alignment.CenterHorizontally ) { // Name + Verified Badge diff --git a/app/src/main/java/com/rosetta/messenger/ui/settings/ProfileLogsScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/settings/ProfileLogsScreen.kt index 2ed3b07..fe8c2b1 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/settings/ProfileLogsScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/settings/ProfileLogsScreen.kt @@ -7,12 +7,14 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.* +import com.rosetta.messenger.ui.icons.TelegramIcons import compose.icons.TablerIcons import compose.icons.tablericons.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalView import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp @@ -25,6 +27,16 @@ fun ProfileLogsScreen( onBack: () -> Unit, onClearLogs: () -> Unit ) { + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as android.app.Activity).window + val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view) + insetsController.isAppearanceLightStatusBars = !isDarkTheme + window.statusBarColor = android.graphics.Color.TRANSPARENT + } + } + val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF) val surfaceColor = if (isDarkTheme) Color(0xFF2C2C2E) else Color(0xFFF2F2F7) val textColor = if (isDarkTheme) Color.White else Color.Black @@ -63,7 +75,7 @@ fun ProfileLogsScreen( ) { IconButton(onClick = onBack) { Icon( - imageVector = TablerIcons.ArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = textColor ) @@ -79,7 +91,7 @@ fun ProfileLogsScreen( ) IconButton(onClick = onClearLogs) { Icon( - imageVector = TablerIcons.Trash, + painter = TelegramIcons.Delete, contentDescription = "Clear logs", tint = secondaryTextColor ) diff --git a/app/src/main/java/com/rosetta/messenger/ui/settings/ProfilePhotoPicker.kt b/app/src/main/java/com/rosetta/messenger/ui/settings/ProfilePhotoPicker.kt index 298071e..8582e5b 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/settings/ProfilePhotoPicker.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/settings/ProfilePhotoPicker.kt @@ -43,8 +43,7 @@ import androidx.compose.ui.window.PopupProperties import androidx.core.content.ContextCompat import coil.compose.AsyncImage import coil.request.ImageRequest -import compose.icons.TablerIcons -import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -292,7 +291,7 @@ fun ProfilePhotoPicker( modifier = Modifier.align(Alignment.CenterStart) ) { Icon( - imageVector = TablerIcons.X, + painter = TelegramIcons.Close, contentDescription = "Close", tint = textColor, modifier = Modifier.size(24.dp) @@ -350,7 +349,7 @@ fun ProfilePhotoPicker( horizontalAlignment = Alignment.CenterHorizontally ) { Icon( - imageVector = TablerIcons.Photo, + painter = TelegramIcons.Photos, contentDescription = null, tint = textColor.copy(alpha = 0.4f), modifier = Modifier.size(64.dp) @@ -501,7 +500,7 @@ private fun PermissionRequest( modifier = Modifier.padding(32.dp) ) { Icon( - imageVector = TablerIcons.Photo, + painter = TelegramIcons.Photos, contentDescription = null, tint = textColor.copy(alpha = 0.5f), modifier = Modifier.size(64.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/settings/ProfileScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/settings/ProfileScreen.kt index fb4fa06..d9790bf 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/settings/ProfileScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/settings/ProfileScreen.kt @@ -44,6 +44,7 @@ import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalHapticFeedback +import androidx.compose.ui.platform.LocalView import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign @@ -74,6 +75,11 @@ import java.util.Locale import com.rosetta.messenger.utils.ImageCropHelper import compose.icons.TablerIcons import compose.icons.tablericons.* +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.res.painterResource +import com.rosetta.messenger.R +import com.rosetta.messenger.ui.icons.TelegramIcons +import androidx.compose.ui.graphics.vector.rememberVectorPainter import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.first @@ -278,6 +284,16 @@ fun ProfileScreen( dialogDao: com.rosetta.messenger.database.DialogDao? = null, backgroundBlurColorId: String = "avatar" ) { + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as android.app.Activity).window + val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view) + insetsController.isAppearanceLightStatusBars = false + window.statusBarColor = android.graphics.Color.TRANSPARENT + } + } + val context = LocalContext.current val activity = context as? FragmentActivity val biometricManager = remember { BiometricAuthManager(context) } @@ -817,7 +833,7 @@ fun ProfileScreen( val scope = rememberCoroutineScope() TelegramToggleItem( - icon = TablerIcons.Bell, + icon = TelegramIcons.Notifications, title = "Push Notifications", isEnabled = notificationsEnabled, onToggle = { @@ -837,7 +853,7 @@ fun ProfileScreen( TelegramSectionTitle(title = "Settings", isDarkTheme = isDarkTheme) TelegramSettingsItem( - icon = TablerIcons.Palette, + icon = TelegramIcons.Theme, title = "Theme", onClick = onNavigateToTheme, isDarkTheme = isDarkTheme, @@ -845,7 +861,7 @@ fun ProfileScreen( ) TelegramSettingsItem( - icon = TablerIcons.Brush, + icon = TelegramIcons.Customize, title = "Appearance", onClick = onNavigateToAppearance, isDarkTheme = isDarkTheme, @@ -853,7 +869,7 @@ fun ProfileScreen( ) TelegramSettingsItem( - icon = TablerIcons.Lock, + icon = TelegramIcons.Secret, title = "Safety", onClick = onNavigateToSafety, isDarkTheme = isDarkTheme, @@ -863,7 +879,7 @@ fun ProfileScreen( // Biometric settings (only show if available) if (biometricAvailable is BiometricAvailability.Available && activity != null) { TelegramSettingsItem( - icon = TablerIcons.Fingerprint, + icon = TelegramIcons.Fingerprint, title = "Biometric Authentication", onClick = { onNavigateToBiometric() @@ -972,10 +988,9 @@ fun ProfileScreen( // Positioned at bottom-right of header, half overlapping content area // Fades out when collapsed or when avatar is expanded // ═══════════════════════════════════════════════════════════ - val cameraButtonAlpha = (1f - collapseProgress * 2.5f).coerceIn(0f, 1f) * - (1f - expansionProgress * 4f).coerceIn(0f, 1f) + val cameraButtonSize = 60.dp + val cameraButtonAlpha = (1f - collapseProgress * 2f).coerceIn(0f, 1f) if (cameraButtonAlpha > 0.01f) { - val cameraButtonSize = 52.dp Box( modifier = Modifier .align(Alignment.TopEnd) @@ -991,15 +1006,15 @@ fun ProfileScreen( clip = false ) .clip(CircleShape) - .background(Color.White) + .background(if (isDarkTheme) Color.White else PrimaryBlue) .clickable { showPhotoPicker = true }, contentAlignment = Alignment.Center ) { Icon( - imageVector = TablerIcons.CameraPlus, + painter = TelegramIcons.AddPhoto, contentDescription = "Change avatar", - tint = Color(0xFF8E8E93), - modifier = Modifier.size(24.dp) + tint = if (isDarkTheme) Color(0xFF8E8E93) else Color.White, + modifier = Modifier.size(26.dp).offset(x = 2.dp) ) } } @@ -1089,7 +1104,10 @@ private fun CollapsingProfileHeader( // 📝 TEXT - внизу header зоны, внутри блока // ═══════════════════════════════════════════════════════════ val textDefaultY = expandedHeight - 70.dp // Ближе к аватарке - val textCollapsedY = statusBarHeight + COLLAPSED_HEADER_HEIGHT / 2 + // Collapsed: center text block vertically in collapsed header + // Text block is ~35dp tall (name 18sp + 2dp spacer + online 13sp) + val textBlockHeight = 35.dp + val textCollapsedY = statusBarHeight + (COLLAPSED_HEADER_HEIGHT - textBlockHeight) / 2 // Текст меняет позицию только при collapse, НЕ при overscroll val textY = androidx.compose.ui.unit.lerp(textDefaultY, textCollapsedY, collapseProgress) @@ -1210,31 +1228,60 @@ private fun CollapsingProfileHeader( } } + // Gradient overlays when avatar is expanded + if (expandFraction > 0.01f) { + // Top gradient + Box( + modifier = Modifier + .fillMaxWidth() + .height(120.dp) + .align(Alignment.TopCenter) + .graphicsLayer { alpha = expandFraction } + .background( + Brush.verticalGradient( + colors = listOf( + Color.Black.copy(alpha = 0.6f), + Color.Transparent + ) + ) + ) + ) + // Bottom gradient + Box( + modifier = Modifier + .fillMaxWidth() + .height(120.dp) + .align(Alignment.BottomCenter) + .graphicsLayer { alpha = expandFraction } + .background( + Brush.verticalGradient( + colors = listOf( + Color.Transparent, + Color.Black.copy(alpha = 0.6f) + ) + ) + ) + ) + } + // ═══════════════════════════════════════════════════════════ - // 🔙 BACK BUTTON - Aligned with text vertical center + // 🔙 BACK BUTTON - At top when expanded, centered when collapsed // ═══════════════════════════════════════════════════════════ + val buttonsExpandedY = statusBarHeight + 8.dp + val buttonsCollapsedY = statusBarHeight + (COLLAPSED_HEADER_HEIGHT - 48.dp) / 2 + val buttonsY = androidx.compose.ui.unit.lerp(buttonsExpandedY, buttonsCollapsedY, collapseProgress) + Box( modifier = Modifier .align(Alignment.TopStart) - .offset(x = 4.dp, y = textY) - .graphicsLayer { - val centerOffsetY = - with(density) { - androidx.compose - .ui - .unit - .lerp(24.dp, 18.dp, collapseProgress) - .toPx() - } - translationY = -centerOffsetY - } + .offset(x = 4.dp, y = buttonsY) .size(48.dp), contentAlignment = Alignment.Center ) { IconButton(onClick = onBack, modifier = Modifier.size(48.dp)) { Icon( - imageVector = TablerIcons.ArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = Color.White, modifier = Modifier.size(24.dp) @@ -1243,23 +1290,12 @@ private fun CollapsingProfileHeader( } // ═══════════════════════════════════════════════════════════ - // ⋮ MENU BUTTON / 💾 SAVE BUTTON - Aligned with text vertical center + // ⋮ MENU BUTTON / 💾 SAVE BUTTON - At top when expanded, centered when collapsed // ═══════════════════════════════════════════════════════════ Box( modifier = Modifier.align(Alignment.TopEnd) - .offset(x = -4.dp, y = textY) - .graphicsLayer { - val centerOffsetY = - with(density) { - androidx.compose - .ui - .unit - .lerp(24.dp, 18.dp, collapseProgress) - .toPx() - } - translationY = -centerOffsetY - }, + .offset(x = -4.dp, y = buttonsY), contentAlignment = Alignment.Center ) { AnimatedVisibility(visible = hasChanges, enter = fadeIn(), exit = fadeOut()) { @@ -1283,7 +1319,7 @@ private fun CollapsingProfileHeader( modifier = Modifier.size(48.dp) ) { Icon( - imageVector = TablerIcons.DotsVertical, + painter = TelegramIcons.More, contentDescription = "Profile menu", tint = Color.White, modifier = Modifier.size(24.dp) @@ -1312,17 +1348,7 @@ private fun CollapsingProfileHeader( // ═══════════════════════════════════════════════════════════ Column( modifier = - Modifier.align(Alignment.TopCenter).offset(y = textY).graphicsLayer { - val centerOffsetY = - with(density) { - androidx.compose - .ui - .unit - .lerp(24.dp, 18.dp, collapseProgress) - .toPx() - } - translationY = -centerOffsetY - }, + Modifier.align(Alignment.TopCenter).offset(y = textY), horizontalAlignment = Alignment.CenterHorizontally ) { Text( @@ -1445,7 +1471,7 @@ fun ProfileCard( modifier = Modifier.align(Alignment.TopStart).statusBarsPadding().padding(4.dp) ) { Icon( - imageVector = TablerIcons.ArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = if (isDarkTheme) Color.White else Color.Black ) @@ -1690,7 +1716,7 @@ fun TelegramCopyField(value: String, fullValue: String, label: String, isDarkThe @Composable private fun TelegramSettingsItem( - icon: ImageVector, + icon: Painter, title: String, onClick: () -> Unit, isDarkTheme: Boolean, @@ -1712,7 +1738,7 @@ private fun TelegramSettingsItem( verticalAlignment = Alignment.CenterVertically ) { Icon( - imageVector = icon, + painter = icon, contentDescription = null, tint = iconColor, modifier = Modifier.size(24.dp) @@ -1740,8 +1766,8 @@ private fun TelegramSettingsItem( } @Composable -private fun TelegramToggleItem( - icon: ImageVector, +fun TelegramToggleItem( + icon: Painter, title: String, subtitle: String? = null, isEnabled: Boolean, @@ -1764,7 +1790,7 @@ private fun TelegramToggleItem( verticalAlignment = Alignment.CenterVertically ) { Icon( - imageVector = icon, + painter = icon, contentDescription = null, tint = iconColor, modifier = Modifier.size(24.dp) @@ -1852,7 +1878,7 @@ private fun TelegramToggleItem( @Composable private fun TelegramBiometricItem(isEnabled: Boolean, onToggle: () -> Unit, isDarkTheme: Boolean) { TelegramToggleItem( - icon = TablerIcons.Fingerprint, + icon = TelegramIcons.Fingerprint, title = "Biometric Authentication", isEnabled = isEnabled, onToggle = onToggle, @@ -1872,7 +1898,7 @@ private fun TelegramLogoutItem(onClick: () -> Unit, isDarkTheme: Boolean) { verticalAlignment = Alignment.CenterVertically ) { Icon( - imageVector = TablerIcons.Logout, + painter = TelegramIcons.Leave, contentDescription = null, tint = redColor, modifier = Modifier.size(24.dp) @@ -1903,7 +1929,7 @@ private fun ProfileSectionTitle(title: String, isDarkTheme: Boolean) { @Composable fun ProfileNavigationItem( - icon: ImageVector, + icon: Painter, iconBackground: Color, title: String, subtitle: String, @@ -1934,7 +1960,7 @@ fun ProfileNavigationItem( contentAlignment = Alignment.Center ) { Icon( - imageVector = icon, + painter = icon, contentDescription = null, tint = Color.White, modifier = Modifier.size(20.dp) @@ -2120,6 +2146,22 @@ fun FullScreenAvatarViewer( ) ) + // Bottom gradient shadow + Box( + modifier = Modifier + .fillMaxWidth() + .height(120.dp) + .align(Alignment.BottomCenter) + .background( + Brush.verticalGradient( + colors = listOf( + Color.Transparent, + Color.Black.copy(alpha = 0.6f) + ) + ) + ) + ) + // Header: back button + name + date Row( modifier = Modifier @@ -2130,7 +2172,7 @@ fun FullScreenAvatarViewer( ) { IconButton(onClick = { showContent = false }) { Icon( - imageVector = TablerIcons.ArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Close", tint = Color.White, modifier = Modifier.size(24.dp) @@ -2158,7 +2200,7 @@ fun FullScreenAvatarViewer( IconButton(onClick = { /* menu */ }) { Icon( - imageVector = TablerIcons.DotsVertical, + painter = TelegramIcons.More, contentDescription = "Menu", tint = Color.White, modifier = Modifier.size(24.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/settings/ThemeScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/settings/ThemeScreen.kt index 69a48df..d49b25c 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/settings/ThemeScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/settings/ThemeScreen.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material3.* import compose.icons.TablerIcons import compose.icons.tablericons.* +import com.rosetta.messenger.ui.icons.TelegramIcons import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment @@ -21,6 +22,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalView import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -33,6 +35,16 @@ fun ThemeScreen( onBack: () -> Unit, onThemeModeChange: (String) -> Unit ) { + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as android.app.Activity).window + val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view) + insetsController.isAppearanceLightStatusBars = !isDarkTheme + window.statusBarColor = android.graphics.Color.TRANSPARENT + } + } + val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF) val surfaceColor = if (isDarkTheme) Color(0xFF2C2C2E) else Color(0xFFF2F2F7) val textColor = if (isDarkTheme) Color.White else Color.Black @@ -63,7 +75,7 @@ fun ThemeScreen( ) { IconButton(onClick = onBack) { Icon( - imageVector = TablerIcons.ArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = textColor ) @@ -209,7 +221,7 @@ private fun TelegramThemeOption( // Radio button if (isSelected) { Icon( - imageVector = TablerIcons.Check, + painter = TelegramIcons.Done, contentDescription = null, tint = Color(0xFF007AFF), modifier = Modifier.size(20.dp) @@ -358,7 +370,7 @@ private fun MessageBubble( if (isMe) { // Read checkmarks (DoneAll icon like in real chat) Icon( - imageVector = TablerIcons.Checks, + painter = TelegramIcons.Done, contentDescription = null, tint = Color(0xFF4FC3F7), // Blue checkmarks for read messages modifier = Modifier.size(14.dp) diff --git a/app/src/main/java/com/rosetta/messenger/ui/settings/UpdatesScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/settings/UpdatesScreen.kt index 178a1b1..fc64bfd 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/settings/UpdatesScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/settings/UpdatesScreen.kt @@ -7,13 +7,16 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.* +import com.rosetta.messenger.ui.icons.TelegramIcons import compose.icons.TablerIcons import compose.icons.tablericons.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalView import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -24,6 +27,16 @@ fun UpdatesScreen( isDarkTheme: Boolean, onBack: () -> Unit ) { + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as android.app.Activity).window + val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view) + insetsController.isAppearanceLightStatusBars = !isDarkTheme + window.statusBarColor = android.graphics.Color.TRANSPARENT + } + } + val versionName = remember { BuildConfig.VERSION_NAME } val buildNumber = remember { BuildConfig.VERSION_CODE.toString() } val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF) @@ -52,7 +65,7 @@ fun UpdatesScreen( ) { IconButton(onClick = onBack) { Icon( - imageVector = TablerIcons.ArrowLeft, + imageVector = TablerIcons.ChevronLeft, contentDescription = "Back", tint = if (isDarkTheme) Color.White else Color.Black ) diff --git a/app/src/main/res/drawable-hdpi/fingerprint.png b/app/src/main/res/drawable-hdpi/fingerprint.png new file mode 100644 index 0000000..d6bd373 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/fingerprint.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_ab_done.png b/app/src/main/res/drawable-hdpi/ic_ab_done.png new file mode 100644 index 0000000..2c1d205 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_ab_done.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_ab_other.png b/app/src/main/res/drawable-hdpi/ic_ab_other.png new file mode 100644 index 0000000..7cfc685 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_ab_other.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_ab_reply.png b/app/src/main/res/drawable-hdpi/ic_ab_reply.png new file mode 100644 index 0000000..88fbba3 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_ab_reply.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_arrow_drop_down.png b/app/src/main/res/drawable-hdpi/ic_arrow_drop_down.png new file mode 100644 index 0000000..f5df4ae Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_arrow_drop_down.png differ diff --git a/app/src/main/res/drawable-hdpi/input_attach.png b/app/src/main/res/drawable-hdpi/input_attach.png new file mode 100644 index 0000000..7c46426 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/input_attach.png differ diff --git a/app/src/main/res/drawable-hdpi/input_keyboard.png b/app/src/main/res/drawable-hdpi/input_keyboard.png new file mode 100644 index 0000000..d57fe9d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/input_keyboard.png differ diff --git a/app/src/main/res/drawable-hdpi/input_smile.png b/app/src/main/res/drawable-hdpi/input_smile.png new file mode 100644 index 0000000..51fa28a Binary files /dev/null and b/app/src/main/res/drawable-hdpi/input_smile.png differ diff --git a/app/src/main/res/drawable-hdpi/menu_unlock.png b/app/src/main/res/drawable-hdpi/menu_unlock.png new file mode 100644 index 0000000..1b582c2 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/menu_unlock.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_add.png b/app/src/main/res/drawable-hdpi/msg_add.png new file mode 100644 index 0000000..dcf8549 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_add.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_addcontact.png b/app/src/main/res/drawable-hdpi/msg_addcontact.png new file mode 100644 index 0000000..7094e21 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_addcontact.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_addphoto.png b/app/src/main/res/drawable-hdpi/msg_addphoto.png new file mode 100644 index 0000000..176e974 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_addphoto.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_arrow_back.png b/app/src/main/res/drawable-hdpi/msg_arrow_back.png new file mode 100644 index 0000000..5f2c056 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_arrow_back.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_arrowright.png b/app/src/main/res/drawable-hdpi/msg_arrowright.png new file mode 100644 index 0000000..29d55f8 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_arrowright.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_autodelete.png b/app/src/main/res/drawable-hdpi/msg_autodelete.png new file mode 100644 index 0000000..37269ad Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_autodelete.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_block.png b/app/src/main/res/drawable-hdpi/msg_block.png new file mode 100644 index 0000000..cd62187 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_block.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_camera.png b/app/src/main/res/drawable-hdpi/msg_camera.png new file mode 100644 index 0000000..103cda3 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_camera.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_close.png b/app/src/main/res/drawable-hdpi/msg_close.png new file mode 100644 index 0000000..0d213d7 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_close.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_contact.png b/app/src/main/res/drawable-hdpi/msg_contact.png new file mode 100644 index 0000000..da35681 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_contact.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_customize.png b/app/src/main/res/drawable-hdpi/msg_customize.png new file mode 100644 index 0000000..6eb7e8d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_customize.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_delete.png b/app/src/main/res/drawable-hdpi/msg_delete.png new file mode 100644 index 0000000..521ea76 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_delete.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_edit.png b/app/src/main/res/drawable-hdpi/msg_edit.png new file mode 100644 index 0000000..9d4bae2 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_edit.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_info.png b/app/src/main/res/drawable-hdpi/msg_info.png new file mode 100644 index 0000000..3bd75f7 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_info.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_leave.png b/app/src/main/res/drawable-hdpi/msg_leave.png new file mode 100644 index 0000000..9cf0ff1 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_leave.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_message.png b/app/src/main/res/drawable-hdpi/msg_message.png new file mode 100644 index 0000000..135a075 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_message.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_mute.png b/app/src/main/res/drawable-hdpi/msg_mute.png new file mode 100644 index 0000000..5487454 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_mute.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_notifications.png b/app/src/main/res/drawable-hdpi/msg_notifications.png new file mode 100644 index 0000000..3e46463 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_notifications.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_palette.png b/app/src/main/res/drawable-hdpi/msg_palette.png new file mode 100644 index 0000000..f92617f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_palette.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_photos.png b/app/src/main/res/drawable-hdpi/msg_photos.png new file mode 100644 index 0000000..13b4853 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_photos.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_pin.png b/app/src/main/res/drawable-hdpi/msg_pin.png new file mode 100644 index 0000000..eb5b5b3 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_pin.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_retry.png b/app/src/main/res/drawable-hdpi/msg_retry.png new file mode 100644 index 0000000..3c8571e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_retry.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_secret.png b/app/src/main/res/drawable-hdpi/msg_secret.png new file mode 100644 index 0000000..9e428aa Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_secret.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_send.png b/app/src/main/res/drawable-hdpi/msg_send.png new file mode 100644 index 0000000..dc70ab6 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_send.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_sendfile.png b/app/src/main/res/drawable-hdpi/msg_sendfile.png new file mode 100644 index 0000000..1236cec Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_sendfile.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_theme.png b/app/src/main/res/drawable-hdpi/msg_theme.png new file mode 100644 index 0000000..290df93 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_theme.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_unpin.png b/app/src/main/res/drawable-hdpi/msg_unpin.png new file mode 100644 index 0000000..7a23866 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_unpin.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_views.png b/app/src/main/res/drawable-hdpi/msg_views.png new file mode 100644 index 0000000..dff6ee8 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_views.png differ diff --git a/app/src/main/res/drawable-hdpi/msg_warning.png b/app/src/main/res/drawable-hdpi/msg_warning.png new file mode 100644 index 0000000..d42de37 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/msg_warning.png differ diff --git a/app/src/main/res/drawable-mdpi/fingerprint.png b/app/src/main/res/drawable-mdpi/fingerprint.png new file mode 100644 index 0000000..9cb7119 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/fingerprint.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_ab_done.png b/app/src/main/res/drawable-mdpi/ic_ab_done.png new file mode 100644 index 0000000..ac961f1 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_ab_done.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_ab_other.png b/app/src/main/res/drawable-mdpi/ic_ab_other.png new file mode 100644 index 0000000..c2db595 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_ab_other.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_ab_reply.png b/app/src/main/res/drawable-mdpi/ic_ab_reply.png new file mode 100644 index 0000000..68c18c0 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_ab_reply.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_arrow_drop_down.png b/app/src/main/res/drawable-mdpi/ic_arrow_drop_down.png new file mode 100644 index 0000000..a671753 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_arrow_drop_down.png differ diff --git a/app/src/main/res/drawable-mdpi/input_attach.png b/app/src/main/res/drawable-mdpi/input_attach.png new file mode 100644 index 0000000..78d32c8 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/input_attach.png differ diff --git a/app/src/main/res/drawable-mdpi/input_keyboard.png b/app/src/main/res/drawable-mdpi/input_keyboard.png new file mode 100644 index 0000000..3bda688 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/input_keyboard.png differ diff --git a/app/src/main/res/drawable-mdpi/input_smile.png b/app/src/main/res/drawable-mdpi/input_smile.png new file mode 100644 index 0000000..a531c29 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/input_smile.png differ diff --git a/app/src/main/res/drawable-mdpi/menu_unlock.png b/app/src/main/res/drawable-mdpi/menu_unlock.png new file mode 100644 index 0000000..e882b17 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/menu_unlock.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_add.png b/app/src/main/res/drawable-mdpi/msg_add.png new file mode 100644 index 0000000..0bbd428 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_add.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_addcontact.png b/app/src/main/res/drawable-mdpi/msg_addcontact.png new file mode 100644 index 0000000..435cff3 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_addcontact.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_addphoto.png b/app/src/main/res/drawable-mdpi/msg_addphoto.png new file mode 100644 index 0000000..a8921ed Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_addphoto.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_arrow_back.png b/app/src/main/res/drawable-mdpi/msg_arrow_back.png new file mode 100644 index 0000000..53ebd2e Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_arrow_back.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_arrowright.png b/app/src/main/res/drawable-mdpi/msg_arrowright.png new file mode 100644 index 0000000..ea66216 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_arrowright.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_autodelete.png b/app/src/main/res/drawable-mdpi/msg_autodelete.png new file mode 100644 index 0000000..d1ca243 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_autodelete.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_block.png b/app/src/main/res/drawable-mdpi/msg_block.png new file mode 100644 index 0000000..2c97a69 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_block.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_camera.png b/app/src/main/res/drawable-mdpi/msg_camera.png new file mode 100644 index 0000000..cc07a52 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_camera.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_close.png b/app/src/main/res/drawable-mdpi/msg_close.png new file mode 100644 index 0000000..c2164aa Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_close.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_contact.png b/app/src/main/res/drawable-mdpi/msg_contact.png new file mode 100644 index 0000000..594b1fd Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_contact.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_customize.png b/app/src/main/res/drawable-mdpi/msg_customize.png new file mode 100644 index 0000000..602f2dd Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_customize.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_delete.png b/app/src/main/res/drawable-mdpi/msg_delete.png new file mode 100644 index 0000000..3de3ae7 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_delete.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_edit.png b/app/src/main/res/drawable-mdpi/msg_edit.png new file mode 100644 index 0000000..d2ba2e4 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_edit.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_info.png b/app/src/main/res/drawable-mdpi/msg_info.png new file mode 100644 index 0000000..13519f6 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_info.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_leave.png b/app/src/main/res/drawable-mdpi/msg_leave.png new file mode 100644 index 0000000..b84b595 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_leave.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_message.png b/app/src/main/res/drawable-mdpi/msg_message.png new file mode 100644 index 0000000..a1ba0e8 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_message.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_mute.png b/app/src/main/res/drawable-mdpi/msg_mute.png new file mode 100644 index 0000000..d682c49 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_mute.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_notifications.png b/app/src/main/res/drawable-mdpi/msg_notifications.png new file mode 100644 index 0000000..6bf5a5d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_notifications.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_palette.png b/app/src/main/res/drawable-mdpi/msg_palette.png new file mode 100644 index 0000000..c1bb7ce Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_palette.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_photos.png b/app/src/main/res/drawable-mdpi/msg_photos.png new file mode 100644 index 0000000..8a4fcb9 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_photos.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_pin.png b/app/src/main/res/drawable-mdpi/msg_pin.png new file mode 100644 index 0000000..1d807cf Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_pin.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_retry.png b/app/src/main/res/drawable-mdpi/msg_retry.png new file mode 100644 index 0000000..43dbb84 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_retry.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_secret.png b/app/src/main/res/drawable-mdpi/msg_secret.png new file mode 100644 index 0000000..ad35994 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_secret.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_send.png b/app/src/main/res/drawable-mdpi/msg_send.png new file mode 100644 index 0000000..5133308 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_send.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_sendfile.png b/app/src/main/res/drawable-mdpi/msg_sendfile.png new file mode 100644 index 0000000..a9c5e02 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_sendfile.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_theme.png b/app/src/main/res/drawable-mdpi/msg_theme.png new file mode 100644 index 0000000..2f21f77 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_theme.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_unpin.png b/app/src/main/res/drawable-mdpi/msg_unpin.png new file mode 100644 index 0000000..f5075a8 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_unpin.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_views.png b/app/src/main/res/drawable-mdpi/msg_views.png new file mode 100644 index 0000000..526c848 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_views.png differ diff --git a/app/src/main/res/drawable-mdpi/msg_warning.png b/app/src/main/res/drawable-mdpi/msg_warning.png new file mode 100644 index 0000000..46f4c82 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/msg_warning.png differ diff --git a/app/src/main/res/drawable-xhdpi/fingerprint.png b/app/src/main/res/drawable-xhdpi/fingerprint.png new file mode 100644 index 0000000..a5a2fa8 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/fingerprint.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_ab_done.png b/app/src/main/res/drawable-xhdpi/ic_ab_done.png new file mode 100644 index 0000000..5493ed8 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_ab_done.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_ab_other.png b/app/src/main/res/drawable-xhdpi/ic_ab_other.png new file mode 100644 index 0000000..228eeea Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_ab_other.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_ab_reply.png b/app/src/main/res/drawable-xhdpi/ic_ab_reply.png new file mode 100644 index 0000000..b4cfe8b Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_ab_reply.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_arrow_drop_down.png b/app/src/main/res/drawable-xhdpi/ic_arrow_drop_down.png new file mode 100644 index 0000000..41ff50e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_arrow_drop_down.png differ diff --git a/app/src/main/res/drawable-xhdpi/input_attach.png b/app/src/main/res/drawable-xhdpi/input_attach.png new file mode 100644 index 0000000..b839d1f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/input_attach.png differ diff --git a/app/src/main/res/drawable-xhdpi/input_keyboard.png b/app/src/main/res/drawable-xhdpi/input_keyboard.png new file mode 100644 index 0000000..6a76dc6 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/input_keyboard.png differ diff --git a/app/src/main/res/drawable-xhdpi/input_smile.png b/app/src/main/res/drawable-xhdpi/input_smile.png new file mode 100644 index 0000000..0d8fd10 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/input_smile.png differ diff --git a/app/src/main/res/drawable-xhdpi/menu_unlock.png b/app/src/main/res/drawable-xhdpi/menu_unlock.png new file mode 100644 index 0000000..787cb53 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/menu_unlock.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_add.png b/app/src/main/res/drawable-xhdpi/msg_add.png new file mode 100644 index 0000000..5ba046d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_add.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_addcontact.png b/app/src/main/res/drawable-xhdpi/msg_addcontact.png new file mode 100644 index 0000000..d8c34d2 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_addcontact.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_addphoto.png b/app/src/main/res/drawable-xhdpi/msg_addphoto.png new file mode 100644 index 0000000..2eaa7e0 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_addphoto.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_arrow_back.png b/app/src/main/res/drawable-xhdpi/msg_arrow_back.png new file mode 100644 index 0000000..1441aed Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_arrow_back.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_arrowright.png b/app/src/main/res/drawable-xhdpi/msg_arrowright.png new file mode 100644 index 0000000..1fc08bb Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_arrowright.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_autodelete.png b/app/src/main/res/drawable-xhdpi/msg_autodelete.png new file mode 100644 index 0000000..891ffc3 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_autodelete.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_block.png b/app/src/main/res/drawable-xhdpi/msg_block.png new file mode 100644 index 0000000..c0c9975 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_block.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_camera.png b/app/src/main/res/drawable-xhdpi/msg_camera.png new file mode 100644 index 0000000..36881c9 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_camera.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_close.png b/app/src/main/res/drawable-xhdpi/msg_close.png new file mode 100644 index 0000000..64ce0d1 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_close.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_contact.png b/app/src/main/res/drawable-xhdpi/msg_contact.png new file mode 100644 index 0000000..81e3a39 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_contact.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_customize.png b/app/src/main/res/drawable-xhdpi/msg_customize.png new file mode 100644 index 0000000..bf1f731 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_customize.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_delete.png b/app/src/main/res/drawable-xhdpi/msg_delete.png new file mode 100644 index 0000000..b614b6f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_delete.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_edit.png b/app/src/main/res/drawable-xhdpi/msg_edit.png new file mode 100644 index 0000000..34e09c5 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_edit.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_info.png b/app/src/main/res/drawable-xhdpi/msg_info.png new file mode 100644 index 0000000..f7eaf50 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_info.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_leave.png b/app/src/main/res/drawable-xhdpi/msg_leave.png new file mode 100644 index 0000000..60d6baa Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_leave.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_message.png b/app/src/main/res/drawable-xhdpi/msg_message.png new file mode 100644 index 0000000..e436073 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_message.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_mute.png b/app/src/main/res/drawable-xhdpi/msg_mute.png new file mode 100644 index 0000000..92c588d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_mute.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_notifications.png b/app/src/main/res/drawable-xhdpi/msg_notifications.png new file mode 100644 index 0000000..e19e99c Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_notifications.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_palette.png b/app/src/main/res/drawable-xhdpi/msg_palette.png new file mode 100644 index 0000000..7aee03e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_palette.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_photos.png b/app/src/main/res/drawable-xhdpi/msg_photos.png new file mode 100644 index 0000000..846090d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_photos.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_pin.png b/app/src/main/res/drawable-xhdpi/msg_pin.png new file mode 100644 index 0000000..b912823 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_pin.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_retry.png b/app/src/main/res/drawable-xhdpi/msg_retry.png new file mode 100644 index 0000000..01dfd41 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_retry.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_secret.png b/app/src/main/res/drawable-xhdpi/msg_secret.png new file mode 100644 index 0000000..2e00602 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_secret.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_send.png b/app/src/main/res/drawable-xhdpi/msg_send.png new file mode 100644 index 0000000..7956eff Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_send.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_sendfile.png b/app/src/main/res/drawable-xhdpi/msg_sendfile.png new file mode 100644 index 0000000..d96bbdb Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_sendfile.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_theme.png b/app/src/main/res/drawable-xhdpi/msg_theme.png new file mode 100644 index 0000000..7ad4f9f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_theme.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_unpin.png b/app/src/main/res/drawable-xhdpi/msg_unpin.png new file mode 100644 index 0000000..8512c1a Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_unpin.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_views.png b/app/src/main/res/drawable-xhdpi/msg_views.png new file mode 100644 index 0000000..eb35732 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_views.png differ diff --git a/app/src/main/res/drawable-xhdpi/msg_warning.png b/app/src/main/res/drawable-xhdpi/msg_warning.png new file mode 100644 index 0000000..63bc0cb Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/msg_warning.png differ diff --git a/app/src/main/res/drawable-xxhdpi/fingerprint.png b/app/src/main/res/drawable-xxhdpi/fingerprint.png new file mode 100644 index 0000000..039e115 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/fingerprint.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_ab_done.png b/app/src/main/res/drawable-xxhdpi/ic_ab_done.png new file mode 100644 index 0000000..115e4ab Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_ab_done.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_ab_other.png b/app/src/main/res/drawable-xxhdpi/ic_ab_other.png new file mode 100644 index 0000000..6fe7f68 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_ab_other.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_ab_reply.png b/app/src/main/res/drawable-xxhdpi/ic_ab_reply.png new file mode 100644 index 0000000..08d18af Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_ab_reply.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow_drop_down.png b/app/src/main/res/drawable-xxhdpi/ic_arrow_drop_down.png new file mode 100644 index 0000000..d5fca22 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_arrow_drop_down.png differ diff --git a/app/src/main/res/drawable-xxhdpi/input_attach.png b/app/src/main/res/drawable-xxhdpi/input_attach.png new file mode 100644 index 0000000..97d2f25 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/input_attach.png differ diff --git a/app/src/main/res/drawable-xxhdpi/input_keyboard.png b/app/src/main/res/drawable-xxhdpi/input_keyboard.png new file mode 100644 index 0000000..8323676 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/input_keyboard.png differ diff --git a/app/src/main/res/drawable-xxhdpi/input_smile.png b/app/src/main/res/drawable-xxhdpi/input_smile.png new file mode 100644 index 0000000..5881a5e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/input_smile.png differ diff --git a/app/src/main/res/drawable-xxhdpi/menu_unlock.png b/app/src/main/res/drawable-xxhdpi/menu_unlock.png new file mode 100644 index 0000000..608f1ba Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/menu_unlock.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_add.png b/app/src/main/res/drawable-xxhdpi/msg_add.png new file mode 100644 index 0000000..63eac80 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_add.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_addcontact.png b/app/src/main/res/drawable-xxhdpi/msg_addcontact.png new file mode 100644 index 0000000..8780f56 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_addcontact.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_addphoto.png b/app/src/main/res/drawable-xxhdpi/msg_addphoto.png new file mode 100644 index 0000000..86df6ae Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_addphoto.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_arrow_back.png b/app/src/main/res/drawable-xxhdpi/msg_arrow_back.png new file mode 100644 index 0000000..7db8dac Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_arrow_back.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_arrowright.png b/app/src/main/res/drawable-xxhdpi/msg_arrowright.png new file mode 100644 index 0000000..34d281e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_arrowright.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_autodelete.png b/app/src/main/res/drawable-xxhdpi/msg_autodelete.png new file mode 100644 index 0000000..97bdce6 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_autodelete.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_block.png b/app/src/main/res/drawable-xxhdpi/msg_block.png new file mode 100644 index 0000000..69af526 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_block.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_camera.png b/app/src/main/res/drawable-xxhdpi/msg_camera.png new file mode 100644 index 0000000..ea3f1ae Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_camera.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_close.png b/app/src/main/res/drawable-xxhdpi/msg_close.png new file mode 100644 index 0000000..ea22067 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_close.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_contact.png b/app/src/main/res/drawable-xxhdpi/msg_contact.png new file mode 100644 index 0000000..b8aa0df Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_contact.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_customize.png b/app/src/main/res/drawable-xxhdpi/msg_customize.png new file mode 100644 index 0000000..0f4f2cc Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_customize.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_delete.png b/app/src/main/res/drawable-xxhdpi/msg_delete.png new file mode 100644 index 0000000..76b1f17 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_delete.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_edit.png b/app/src/main/res/drawable-xxhdpi/msg_edit.png new file mode 100644 index 0000000..e392327 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_edit.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_info.png b/app/src/main/res/drawable-xxhdpi/msg_info.png new file mode 100644 index 0000000..ed8c8bb Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_info.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_leave.png b/app/src/main/res/drawable-xxhdpi/msg_leave.png new file mode 100644 index 0000000..9ccd1ae Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_leave.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_message.png b/app/src/main/res/drawable-xxhdpi/msg_message.png new file mode 100644 index 0000000..f5b953c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_message.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_mute.png b/app/src/main/res/drawable-xxhdpi/msg_mute.png new file mode 100644 index 0000000..9538eaf Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_mute.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_notifications.png b/app/src/main/res/drawable-xxhdpi/msg_notifications.png new file mode 100644 index 0000000..b6f7b26 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_notifications.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_palette.png b/app/src/main/res/drawable-xxhdpi/msg_palette.png new file mode 100644 index 0000000..fb96c36 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_palette.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_photos.png b/app/src/main/res/drawable-xxhdpi/msg_photos.png new file mode 100644 index 0000000..4ece2a1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_photos.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_pin.png b/app/src/main/res/drawable-xxhdpi/msg_pin.png new file mode 100644 index 0000000..455413b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_pin.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_retry.png b/app/src/main/res/drawable-xxhdpi/msg_retry.png new file mode 100644 index 0000000..e9d6c37 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_retry.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_secret.png b/app/src/main/res/drawable-xxhdpi/msg_secret.png new file mode 100644 index 0000000..6ed96e8 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_secret.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_send.png b/app/src/main/res/drawable-xxhdpi/msg_send.png new file mode 100644 index 0000000..0bb8269 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_send.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_sendfile.png b/app/src/main/res/drawable-xxhdpi/msg_sendfile.png new file mode 100644 index 0000000..27dee03 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_sendfile.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_theme.png b/app/src/main/res/drawable-xxhdpi/msg_theme.png new file mode 100644 index 0000000..1128d54 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_theme.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_unpin.png b/app/src/main/res/drawable-xxhdpi/msg_unpin.png new file mode 100644 index 0000000..b702fd7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_unpin.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_views.png b/app/src/main/res/drawable-xxhdpi/msg_views.png new file mode 100644 index 0000000..26fdc8f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_views.png differ diff --git a/app/src/main/res/drawable-xxhdpi/msg_warning.png b/app/src/main/res/drawable-xxhdpi/msg_warning.png new file mode 100644 index 0000000..96f7beb Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/msg_warning.png differ