refactor: Clean up imports and improve code formatting in OtherProfileScreen

This commit is contained in:
k1ngsterr1
2026-01-31 04:09:28 +05:00
parent 3ed4986393
commit c6f1998dc9

View File

@@ -1,32 +1,21 @@
package com.rosetta.messenger.ui.settings
import androidx.activity.compose.BackHandler
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
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.*
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.lifecycle.viewmodel.compose.viewModel
import com.rosetta.messenger.data.MessageRepository
import com.rosetta.messenger.database.RosettaDatabase
import com.rosetta.messenger.ui.chats.ChatViewModel
import com.rosetta.messenger.ui.chats.ChatsListViewModel
import com.rosetta.messenger.ui.onboarding.PrimaryBlue
import com.rosetta.messenger.ui.components.VerifiedBadge
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
@@ -41,17 +30,22 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
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.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.rosetta.messenger.data.MessageRepository
import com.rosetta.messenger.database.RosettaDatabase
import com.rosetta.messenger.network.SearchUser
import com.rosetta.messenger.repository.AvatarRepository
import com.rosetta.messenger.ui.chats.ChatViewModel
import com.rosetta.messenger.ui.chats.ChatsListViewModel
import com.rosetta.messenger.ui.components.AvatarImage
import com.rosetta.messenger.ui.components.BlurredAvatarBackground
import com.rosetta.messenger.ui.components.VerifiedBadge
import com.rosetta.messenger.ui.onboarding.PrimaryBlue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.math.roundToInt
// Collapsing header constants
private val EXPANDED_HEADER_HEIGHT_OTHER = 280.dp
@@ -84,9 +78,7 @@ fun OtherProfileScreen(
val coroutineScope = rememberCoroutineScope()
// 🔥 Загружаем статус блокировки при открытии экрана
LaunchedEffect(user.publicKey) {
isBlocked = chatsListViewModel.isUserBlocked(user.publicKey)
}
LaunchedEffect(user.publicKey) { isBlocked = chatsListViewModel.isUserBlocked(user.publicKey) }
// 🎹 Для закрытия клавиатуры
val keyboardController = LocalSoftwareKeyboardController.current
@@ -103,7 +95,9 @@ fun OtherProfileScreen(
// <20>🟢 Наблюдаем за онлайн статусом пользователя в реальном времени
val messageRepository = remember { MessageRepository.getInstance(context) }
val onlineStatus by messageRepository.observeUserOnlineStatus(user.publicKey)
val onlineStatus by
messageRepository
.observeUserOnlineStatus(user.publicKey)
.collectAsState(initial = false to 0L)
val isOnline = onlineStatus.first
val lastSeen = onlineStatus.second
@@ -112,15 +106,14 @@ fun OtherProfileScreen(
val density = LocalDensity.current
val statusBarHeight = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()
val expandedHeightPx = with(density) { (EXPANDED_HEADER_HEIGHT_OTHER + statusBarHeight).toPx() }
val collapsedHeightPx = with(density) { (COLLAPSED_HEADER_HEIGHT_OTHER + statusBarHeight).toPx() }
val collapsedHeightPx =
with(density) { (COLLAPSED_HEADER_HEIGHT_OTHER + statusBarHeight).toPx() }
var scrollOffset by remember { mutableFloatStateOf(0f) }
val maxScrollOffset = expandedHeightPx - collapsedHeightPx
val collapseProgress by remember {
derivedStateOf {
(scrollOffset / maxScrollOffset).coerceIn(0f, 1f)
}
derivedStateOf { (scrollOffset / maxScrollOffset).coerceIn(0f, 1f) }
}
val nestedScrollConnection = remember {
@@ -128,14 +121,17 @@ fun OtherProfileScreen(
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
val delta = available.y
val newOffset = scrollOffset - delta
val consumed = when {
val consumed =
when {
delta < 0 && scrollOffset < maxScrollOffset -> {
val consumed = (newOffset.coerceIn(0f, maxScrollOffset) - scrollOffset)
val consumed =
(newOffset.coerceIn(0f, maxScrollOffset) - scrollOffset)
scrollOffset = newOffset.coerceIn(0f, maxScrollOffset)
-consumed
}
delta > 0 && scrollOffset > 0 -> {
val consumed = scrollOffset - newOffset.coerceIn(0f, maxScrollOffset)
val consumed =
scrollOffset - newOffset.coerceIn(0f, maxScrollOffset)
scrollOffset = newOffset.coerceIn(0f, maxScrollOffset)
consumed
}
@@ -150,16 +146,21 @@ fun OtherProfileScreen(
BackHandler { onBack() }
Box(
modifier = Modifier
.fillMaxSize()
modifier =
Modifier.fillMaxSize()
.background(backgroundColor)
.nestedScroll(nestedScrollConnection)
) {
// Scrollable content
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(top = with(density) { (expandedHeightPx - scrollOffset).toDp() })
modifier =
Modifier.fillMaxSize()
.padding(
top =
with(density) {
(expandedHeightPx - scrollOffset).toDp()
}
)
) {
item {
Spacer(modifier = Modifier.height(16.dp))
@@ -269,14 +270,16 @@ private fun CollapsingOtherProfileHeader(
val expandedHeight = EXPANDED_HEADER_HEIGHT_OTHER + statusBarHeight
val collapsedHeight = COLLAPSED_HEADER_HEIGHT_OTHER + statusBarHeight
val headerHeight = androidx.compose.ui.unit.lerp(expandedHeight, collapsedHeight, collapseProgress)
val headerHeight =
androidx.compose.ui.unit.lerp(expandedHeight, collapsedHeight, collapseProgress)
// Avatar animation
val avatarCenterX = (screenWidthDp - AVATAR_SIZE_EXPANDED_OTHER) / 2
val avatarStartY = statusBarHeight + 32.dp
val avatarEndY = statusBarHeight - 60.dp
val avatarY = androidx.compose.ui.unit.lerp(avatarStartY, avatarEndY, collapseProgress)
val avatarSize = androidx.compose.ui.unit.lerp(AVATAR_SIZE_EXPANDED_OTHER, 0.dp, collapseProgress)
val avatarSize =
androidx.compose.ui.unit.lerp(AVATAR_SIZE_EXPANDED_OTHER, 0.dp, collapseProgress)
val avatarFontSize = androidx.compose.ui.unit.lerp(40.sp, 0.sp, collapseProgress)
// Text animation - always centered
@@ -287,11 +290,7 @@ private fun CollapsingOtherProfileHeader(
val nameFontSize = androidx.compose.ui.unit.lerp(24.sp, 18.sp, collapseProgress)
val onlineFontSize = androidx.compose.ui.unit.lerp(14.sp, 13.sp, collapseProgress)
Box(
modifier = Modifier
.fillMaxWidth()
.height(headerHeight)
) {
Box(modifier = Modifier.fillMaxWidth().height(headerHeight)) {
// ═══════════════════════════════════════════════════════════
// 🎨 BLURRED AVATAR BACKGROUND
// ═══════════════════════════════════════════════════════════
@@ -307,20 +306,17 @@ private fun CollapsingOtherProfileHeader(
// 🔙 BACK BUTTON
// ═══════════════════════════════════════════════════════════
Box(
modifier = Modifier
.padding(top = statusBarHeight)
modifier =
Modifier.padding(top = statusBarHeight)
.padding(start = 4.dp, top = 4.dp)
.size(48.dp),
contentAlignment = Alignment.Center
) {
IconButton(
onClick = onBack,
modifier = Modifier.size(48.dp)
) {
IconButton(onClick = onBack, modifier = Modifier.size(48.dp)) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = "Back",
tint = if (isColorLight(avatarColors.backgroundColor)) Color.Black else Color.White,
tint = if (isDarkTheme) Color.White else Color(0xFF007AFF),
modifier = Modifier.size(24.dp)
)
}
@@ -330,21 +326,20 @@ private fun CollapsingOtherProfileHeader(
// ⋮ MENU BUTTON (top right corner)
// ═══════════════════════════════════════════════════════════
Box(
modifier = Modifier
.align(Alignment.TopEnd)
modifier =
Modifier.align(Alignment.TopEnd)
.padding(top = statusBarHeight)
.padding(end = 4.dp, top = 4.dp)
.size(48.dp),
contentAlignment = Alignment.Center
) {
IconButton(
onClick = { onAvatarMenuChange(true) },
modifier = Modifier.size(48.dp)
) {
IconButton(onClick = { onAvatarMenuChange(true) }, modifier = Modifier.size(48.dp)) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "Profile menu",
tint = if (isColorLight(avatarColors.backgroundColor)) Color.Black else Color.White,
tint =
if (isColorLight(avatarColors.backgroundColor)) Color.Black
else Color.White,
modifier = Modifier.size(24.dp)
)
}
@@ -371,9 +366,12 @@ private fun CollapsingOtherProfileHeader(
// ═══════════════════════════════════════════════════════════
if (avatarSize > 1.dp) {
Box(
modifier = Modifier
.offset(
x = avatarCenterX + (AVATAR_SIZE_EXPANDED_OTHER - avatarSize) / 2,
modifier =
Modifier.offset(
x =
avatarCenterX +
(AVATAR_SIZE_EXPANDED_OTHER -
avatarSize) / 2,
y = avatarY
)
.size(avatarSize)
@@ -396,12 +394,15 @@ private fun CollapsingOtherProfileHeader(
// 📝 TEXT BLOCK - Name + Verified + Online, always centered
// ═══════════════════════════════════════════════════════════
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()
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
},
@@ -416,7 +417,9 @@ private fun CollapsingOtherProfileHeader(
text = name,
fontSize = nameFontSize,
fontWeight = FontWeight.SemiBold,
color = if (isColorLight(avatarColors.backgroundColor)) Color.Black else Color.White,
color =
if (isColorLight(avatarColors.backgroundColor)) Color.Black
else Color.White,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
textAlign = TextAlign.Center
@@ -424,10 +427,7 @@ private fun CollapsingOtherProfileHeader(
if (verified > 0) {
Spacer(modifier = Modifier.width(4.dp))
VerifiedBadge(
verified = verified,
size = (nameFontSize.value * 0.8f).toInt()
)
VerifiedBadge(verified = verified, size = (nameFontSize.value * 0.8f).toInt())
}
}
@@ -437,10 +437,13 @@ private fun CollapsingOtherProfileHeader(
Text(
text = if (isOnline) "online" else "offline",
fontSize = onlineFontSize,
color = if (isOnline) {
color =
if (isOnline) {
Color(0xFF4CAF50)
} else {
if (isColorLight(avatarColors.backgroundColor)) Color.Black.copy(alpha = 0.6f) else Color.White.copy(alpha = 0.6f)
if (isColorLight(avatarColors.backgroundColor))
Color.Black.copy(alpha = 0.6f)
else Color.White.copy(alpha = 0.6f)
}
)
}
@@ -451,17 +454,13 @@ private fun CollapsingOtherProfileHeader(
// 🚫 BLOCK/UNBLOCK ITEM
// ═══════════════════════════════════════════════════════════
@Composable
private fun TelegramBlockItem(
isBlocked: Boolean,
onToggle: () -> Unit,
isDarkTheme: Boolean
) {
private fun TelegramBlockItem(isBlocked: Boolean, onToggle: () -> Unit, isDarkTheme: Boolean) {
val textColor = if (isDarkTheme) Color.White else Color.Black
val iconColor = PrimaryBlue
Row(
modifier = Modifier
.fillMaxWidth()
modifier =
Modifier.fillMaxWidth()
.clickable(onClick = onToggle)
.padding(horizontal = 16.dp, vertical = 14.dp),
verticalAlignment = Alignment.CenterVertically
@@ -484,7 +483,9 @@ private fun TelegramBlockItem(
)
Spacer(modifier = Modifier.height(2.dp))
Text(
text = if (isBlocked) "Allow this user to message you" else "Prevent this user from messaging you",
text =
if (isBlocked) "Allow this user to message you"
else "Prevent this user from messaging you",
fontSize = 13.sp,
color = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666),
lineHeight = 16.sp