feat: Enhance user profile and settings screens

- Updated ChatDetailScreen to pass user data on profile click.
- Added BackupScreen for seed phrase recovery with password verification.
- Introduced OtherProfileScreen for viewing and managing other users' profiles.
- Created SafetyScreen for account security options including backup and deletion.
- Developed ThemeScreen for theme customization with light, dark, and system modes.
- Implemented UpdatesScreen to display app version and check for updates.
- Removed unused navigation item for updates from ProfileScreen.
This commit is contained in:
k1ngsterr1
2026-01-20 18:59:44 +05:00
parent d78000aa3f
commit c42dd57e3d
8 changed files with 1533 additions and 130 deletions

View File

@@ -39,7 +39,12 @@ import com.rosetta.messenger.ui.chats.ChatsListScreen
import com.rosetta.messenger.ui.chats.SearchScreen
import com.rosetta.messenger.ui.components.OptimizedEmojiCache
import com.rosetta.messenger.ui.onboarding.OnboardingScreen
import com.rosetta.messenger.ui.settings.BackupScreen
import com.rosetta.messenger.ui.settings.OtherProfileScreen
import com.rosetta.messenger.ui.settings.ProfileScreen
import com.rosetta.messenger.ui.settings.SafetyScreen
import com.rosetta.messenger.ui.settings.ThemeScreen
import com.rosetta.messenger.ui.settings.UpdatesScreen
import com.rosetta.messenger.ui.splash.SplashScreen
import com.rosetta.messenger.ui.theme.RosettaAndroidTheme
import java.text.SimpleDateFormat
@@ -439,79 +444,152 @@ fun MainScreen(
var selectedUser by remember { mutableStateOf<SearchUser?>(null) }
var showSearchScreen by remember { mutableStateOf(false) }
var showProfileScreen by remember { mutableStateOf(false) }
var showOtherProfileScreen by remember { mutableStateOf(false) }
var selectedOtherUser by remember { mutableStateOf<SearchUser?>(null) }
// Дополнительные экраны настроек
var showUpdatesScreen by remember { mutableStateOf(false) }
var showThemeScreen by remember { mutableStateOf(false) }
var showSafetyScreen by remember { mutableStateOf(false) }
var showBackupScreen by remember { mutableStateOf(false) }
// 🔥 TELEGRAM-STYLE анимация - чистый slide БЕЗ прозрачности
AnimatedContent(
targetState = Pair(Pair(selectedUser, showSearchScreen), showProfileScreen),
transitionSpec = {
val isEnteringChat = targetState.first.first != null && initialState.first.first == null
val isExitingChat = targetState.first.first == null && initialState.first.first != null
val isEnteringSearch = targetState.first.second && !initialState.first.second
val isExitingSearch = !targetState.first.second && initialState.first.second
val isEnteringProfile = targetState.second && !initialState.second
val isExitingProfile = !targetState.second && initialState.second
// 🔥 Простая навигация с fade-in анимацией
Box(modifier = Modifier.fillMaxSize()) {
// Base layer - chats list
androidx.compose.animation.AnimatedVisibility(
visible = !showBackupScreen && !showSafetyScreen && !showThemeScreen &&
!showUpdatesScreen && selectedUser == null && !showSearchScreen &&
!showProfileScreen && !showOtherProfileScreen,
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(200))
) {
ChatsListScreen(
isDarkTheme = isDarkTheme,
accountName = accountName,
accountPhone = accountPhone,
accountPublicKey = accountPublicKey,
accountPrivateKey = accountPrivateKey,
privateKeyHash = privateKeyHash,
onToggleTheme = onToggleTheme,
onProfileClick = {
showProfileScreen = true
},
onNewGroupClick = {
// TODO: Navigate to new group
},
onCallsClick = {
// TODO: Navigate to calls
},
onSavedMessagesClick = {
// Открываем чат с самим собой (Saved Messages)
selectedUser =
SearchUser(
title = "Saved Messages",
username = "",
publicKey = accountPublicKey,
verified = 0,
online = 1
)
},
onSettingsClick = { showProfileScreen = true },
onInviteFriendsClick = {
// TODO: Share invite link
},
onSearchClick = { showSearchScreen = true },
onNewChat = {
// TODO: Show new chat screen
},
onUserSelect = { selectedChatUser -> selectedUser = selectedChatUser },
onLogout = onLogout
)
}
when {
// 🚀 Вход в чат - плавный fade
isEnteringChat -> {
fadeIn(animationSpec = tween(200)) togetherWith
fadeOut(animationSpec = tween(150))
// Other screens with fade animation
androidx.compose.animation.AnimatedVisibility(
visible = showBackupScreen,
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(200))
) {
if (showBackupScreen) {
BackupScreen(
isDarkTheme = isDarkTheme,
onBack = { showBackupScreen = false },
onVerifyPassword = { password ->
// TODO: Implement password verification
if (password == "test") {
"word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12"
} else null
}
)
}
}
// 🔙 Выход из чата - плавный fade
isExitingChat -> {
fadeIn(animationSpec = tween(200)) togetherWith
fadeOut(animationSpec = tween(150))
androidx.compose.animation.AnimatedVisibility(
visible = showSafetyScreen,
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(200))
) {
if (showSafetyScreen) {
SafetyScreen(
isDarkTheme = isDarkTheme,
accountPublicKey = accountPublicKey,
onBack = { showSafetyScreen = false },
onBackupClick = { showBackupScreen = true },
onDeleteAccount = {
// TODO: Implement account deletion
Log.d("MainActivity", "Delete account requested")
}
)
}
}
// 🔍 Вход в Search - плавный fade
isEnteringSearch -> {
fadeIn(animationSpec = tween(200)) togetherWith
fadeOut(animationSpec = tween(150))
androidx.compose.animation.AnimatedVisibility(
visible = showThemeScreen,
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(200))
) {
if (showThemeScreen) {
ThemeScreen(
isDarkTheme = isDarkTheme,
onBack = { showThemeScreen = false },
onThemeChange = { isDark ->
onToggleTheme()
}
)
}
}
// 🔙 Выход из Search - плавный fade
isEnteringSearch -> {
fadeIn(animationSpec = tween(200)) togetherWith
fadeOut(animationSpec = tween(150))
}
androidx.compose.animation.AnimatedVisibility(
visible = showUpdatesScreen,
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(200))
) {
if (showUpdatesScreen) {
UpdatesScreen(
isDarkTheme = isDarkTheme,
onBack = { showUpdatesScreen = false }
)
}
}
// 🔙 Выход из Search - плавный fade
isExitingSearch -> {
fadeIn(animationSpec = tween(200)) togetherWith
fadeOut(animationSpec = tween(150))
}
// 👤 Вход в Profile - плавный fade
isEnteringProfile -> {
fadeIn(animationSpec = tween(200)) togetherWith
fadeOut(animationSpec = tween(150))
}
// 🔙 Выход из Profile - плавный fade
isExitingProfile -> {
fadeIn(animationSpec = tween(200)) togetherWith
fadeOut(animationSpec = tween(150))
}
// Default - мгновенный переход
else -> {
EnterTransition.None togetherWith ExitTransition.None
}
}
},
label = "screenNavigation"
) { (chatAndSearchState, isProfileOpen) ->
val (currentUser, isSearchOpen) = chatAndSearchState
when {
currentUser != null -> {
androidx.compose.animation.AnimatedVisibility(
visible = selectedUser != null,
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(200))
) {
if (selectedUser != null) {
// Экран чата
ChatDetailScreen(
user = currentUser,
user = selectedUser!!,
currentUserPublicKey = accountPublicKey,
currentUserPrivateKey = accountPrivateKey,
isDarkTheme = isDarkTheme,
onBack = { selectedUser = null },
onUserProfileClick = { user ->
// Открываем профиль другого пользователя
selectedOtherUser = user
showOtherProfileScreen = true
},
onNavigateToChat = { publicKey ->
// 📨 Forward: переход в выбранный чат
// Нужно получить SearchUser из публичного ключа
@@ -528,7 +606,14 @@ fun MainScreen(
}
)
}
isSearchOpen -> {
}
androidx.compose.animation.AnimatedVisibility(
visible = showSearchScreen,
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(200))
) {
if (showSearchScreen) {
// Экран поиска
SearchScreen(
privateKeyHash = privateKeyHash,
@@ -542,7 +627,14 @@ fun MainScreen(
}
)
}
isProfileOpen -> {
}
androidx.compose.animation.AnimatedVisibility(
visible = showProfileScreen,
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(200))
) {
if (showProfileScreen) {
// Экран профиля
ProfileScreen(
isDarkTheme = isDarkTheme,
@@ -554,67 +646,30 @@ fun MainScreen(
// TODO: Save profile changes
Log.d("MainActivity", "Saving profile: name=$name, username=$username")
},
onLogout = {
// TODO: Implement logout
Log.d("MainActivity", "Logout requested")
},
onLogout = onLogout,
onNavigateToTheme = {
// Toggle theme for now
onToggleTheme()
showThemeScreen = true
},
onNavigateToSafety = {
// TODO: Navigate to safety screen
Log.d("MainActivity", "Navigate to safety")
},
onNavigateToUpdates = {
// TODO: Navigate to updates screen
Log.d("MainActivity", "Navigate to updates")
showSafetyScreen = true
}
)
}
else -> {
// Список чатов
ChatsListScreen(
isDarkTheme = isDarkTheme,
accountName = accountName,
accountPhone = accountPhone,
accountPublicKey = accountPublicKey,
accountPrivateKey = accountPrivateKey,
privateKeyHash = privateKeyHash,
onToggleTheme = onToggleTheme,
onProfileClick = {
showProfileScreen = true
},
onNewGroupClick = {
// TODO: Navigate to new group
},
onContactsClick = {
// TODO: Navigate to contacts
},
onCallsClick = {
// TODO: Navigate to calls
},
onSavedMessagesClick = {
// Открываем чат с самим собой (Saved Messages)
selectedUser =
SearchUser(
title = "Saved Messages",
username = "",
publicKey = accountPublicKey,
verified = 0,
online = 1
)
},
onSettingsClick = { showProfileScreen = true },
onInviteFriendsClick = {
// TODO: Share invite link
},
onSearchClick = { showSearchScreen = true },
onNewChat = {
// TODO: Show new chat screen
},
onUserSelect = { selectedChatUser -> selectedUser = selectedChatUser },
onLogout = onLogout
}
androidx.compose.animation.AnimatedVisibility(
visible = showOtherProfileScreen,
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(200))
) {
if (showOtherProfileScreen && selectedOtherUser != null) {
OtherProfileScreen(
user = selectedOtherUser!!,
isDarkTheme = isDarkTheme,
onBack = {
showOtherProfileScreen = false
selectedOtherUser = null
}
)
}
}