diff --git a/app/src/main/java/com/rosetta/messenger/MainActivity.kt b/app/src/main/java/com/rosetta/messenger/MainActivity.kt index 1ce0afc..6716fe4 100644 --- a/app/src/main/java/com/rosetta/messenger/MainActivity.kt +++ b/app/src/main/java/com/rosetta/messenger/MainActivity.kt @@ -496,6 +496,7 @@ private fun EncryptedAccount.toAccountInfo(): AccountInfo { */ sealed class Screen { data object Profile : Screen() + data object ProfileFromChat : Screen() data object Requests : Screen() data object Search : Screen() data object GroupSetup : Screen() @@ -600,6 +601,9 @@ fun MainScreen( // Derived visibility — only triggers recomposition when THIS screen changes val isProfileVisible by remember { derivedStateOf { navStack.any { it is Screen.Profile } } } + val isProfileFromChatVisible by remember { + derivedStateOf { navStack.any { it is Screen.ProfileFromChat } } + } val isRequestsVisible by remember { derivedStateOf { navStack.any { it is Screen.Requests } } } val isSearchVisible by remember { derivedStateOf { navStack.any { it is Screen.Search } } } val isGroupSetupVisible by remember { derivedStateOf { navStack.any { it is Screen.GroupSetup } } } @@ -662,11 +666,18 @@ fun MainScreen( navStack = navStack.dropLast(1) } fun openOwnProfile() { - navStack = + val filteredStack = navStack.filterNot { it is Screen.ChatDetail || it is Screen.OtherProfile || it is Screen.GroupInfo } - pushScreen(Screen.Profile) + // Single state update avoids intermediate frame (chat list flash/jitter) when opening + // profile from a mention inside chat. + navStack = + if (filteredStack.lastOrNull() == Screen.Profile) { + filteredStack + } else { + filteredStack + Screen.Profile + } } fun popProfileAndChildren() { navStack = @@ -1003,8 +1014,9 @@ fun MainScreen( onBack = { popChatAndChildren() }, onUserProfileClick = { user -> if (isCurrentAccountUser(user)) { - // Свой профиль — открываем My Profile - openOwnProfile() + // Свой профиль из чата открываем поверх текущего чата, + // чтобы возврат оставался в этот чат, а не в chat list. + pushScreen(Screen.ProfileFromChat) } else { // Открываем профиль другого пользователя pushScreen(Screen.OtherProfile(user)) @@ -1028,6 +1040,39 @@ fun MainScreen( } } + SwipeBackContainer( + isVisible = isProfileFromChatVisible, + onBack = { navStack = navStack.filterNot { it is Screen.ProfileFromChat } }, + isDarkTheme = isDarkTheme, + layer = 1, + propagateBackgroundProgress = false + ) { + ProfileScreen( + isDarkTheme = isDarkTheme, + accountName = accountName, + accountUsername = accountUsername, + accountVerified = accountVerified, + accountPublicKey = accountPublicKey, + accountPrivateKeyHash = privateKeyHash, + onBack = { navStack = navStack.filterNot { it is Screen.ProfileFromChat } }, + onSaveProfile = { name, username -> + accountName = name + accountUsername = username + mainScreenScope.launch { onAccountInfoUpdated() } + }, + onLogout = onLogout, + onNavigateToTheme = { pushScreen(Screen.Theme) }, + onNavigateToAppearance = { pushScreen(Screen.Appearance) }, + onNavigateToSafety = { pushScreen(Screen.Safety) }, + onNavigateToLogs = { pushScreen(Screen.Logs) }, + onNavigateToBiometric = { pushScreen(Screen.Biometric) }, + viewModel = profileViewModel, + avatarRepository = avatarRepository, + dialogDao = RosettaDatabase.getDatabase(context).dialogDao(), + backgroundBlurColorId = backgroundBlurColorId + ) + } + var isGroupInfoSwipeEnabled by remember { mutableStateOf(true) } LaunchedEffect(selectedGroup?.publicKey) { isGroupInfoSwipeEnabled = true