package core.presentation.components import androidx.compose.animation.* import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.detectTransformGestures import androidx.compose.foundation.gestures.rememberTransformableState import androidx.compose.foundation.gestures.transformable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Download import androidx.compose.material.icons.filled.InsertDriveFile import androidx.compose.material3.* 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.graphics.graphicsLayer import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import coil.compose.AsyncImage import chats.domain.model.Media import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import android.content.Intent import android.net.Uri import kotlinx.coroutines.launch @OptIn(androidx.compose.foundation.ExperimentalFoundationApi::class) @Composable fun AppMediaLightbox( mediaList: List, initialIndex: Int = 0, onClose: () -> Unit ) { val context = LocalContext.current val scope = rememberCoroutineScope() val pagerState = rememberPagerState(initialPage = initialIndex, pageCount = { mediaList.size }) Dialog( onDismissRequest = onClose, properties = DialogProperties( usePlatformDefaultWidth = false, decorFitsSystemWindows = false ) ) { Box( modifier = Modifier .fillMaxSize() .background(Color.Black) ) { HorizontalPager( state = pagerState, modifier = Modifier.fillMaxSize(), pageSpacing = 16.dp, beyondBoundsPageCount = 1 ) { page -> val media = mediaList[page] Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { if (media.type.startsWith("video")) { val isCurrentPage = pagerState.currentPage == page AppVideoPlayer( url = media.url, modifier = Modifier.fillMaxSize(), useController = true, autoPlay = isCurrentPage // Только если страница активна ) } else if (media.type.startsWith("image") || media.type.contains("gif")) { var scale by remember { mutableFloatStateOf(1f) } var offset by remember { mutableStateOf(androidx.compose.ui.geometry.Offset.Zero) } AsyncImage( model = media.url, imageLoader = core.utils.CoilUtils.getGifImageLoader(LocalContext.current), contentDescription = null, modifier = Modifier .fillMaxSize() .graphicsLayer( scaleX = scale, scaleY = scale, translationX = offset.x, translationY = offset.y ), contentScale = ContentScale.Fit ) } else { // Document / File placeholder in Lightbox Column( modifier = Modifier.fillMaxSize().padding(32.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Icon( imageVector = Icons.Default.InsertDriveFile, contentDescription = null, tint = Color.White, modifier = Modifier.size(100.dp) ) Spacer(modifier = Modifier.height(24.dp)) Text( text = media.filename ?: "File", color = Color.White, style = MaterialTheme.typography.headlineSmall, textAlign = androidx.compose.ui.text.style.TextAlign.Center ) Spacer(modifier = Modifier.height(32.dp)) Button( onClick = { try { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(media.url)) context.startActivity(intent) } catch (e: Exception) { // Handle error (no app to open) } }, colors = ButtonDefaults.buttonColors(containerColor = Color.White, contentColor = Color.Black) ) { Text("Открыть в приложении") } } } } } // Top Bar Row( modifier = Modifier .fillMaxWidth() .statusBarsPadding() .padding(16.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { IconButton( onClick = onClose, modifier = Modifier .clip(CircleShape) .background(Color.Black.copy(alpha = 0.5f)) ) { Icon(Icons.Default.Close, contentDescription = null, tint = Color.White) } if (mediaList.isNotEmpty()) { Text( text = "${pagerState.currentPage + 1} / ${mediaList.size}", color = Color.White, style = MaterialTheme.typography.titleMedium ) } IconButton( onClick = { val currentMedia = mediaList[pagerState.currentPage] scope.launch { core.utils.DownloadUtils.downloadMedia(context, currentMedia.url, currentMedia.filename) } }, modifier = Modifier .clip(CircleShape) .background(Color.Black.copy(alpha = 0.5f)) ) { Icon(Icons.Default.Download, contentDescription = null, tint = Color.White) } } } } }