diff --git a/app/src/main/java/com/codekotliners/memify/features/create/presentation/ui/CreateScreen.kt b/app/src/main/java/com/codekotliners/memify/features/create/presentation/ui/CreateScreen.kt index cebd2f9c..77a5a91d 100644 --- a/app/src/main/java/com/codekotliners/memify/features/create/presentation/ui/CreateScreen.kt +++ b/app/src/main/java/com/codekotliners/memify/features/create/presentation/ui/CreateScreen.kt @@ -1,6 +1,9 @@ package com.codekotliners.memify.features.create.presentation.ui +import android.app.Activity import android.content.Intent +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.Image @@ -23,6 +26,7 @@ import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.filled.KeyboardArrowUp import androidx.compose.material.icons.filled.MoreVert @@ -31,6 +35,7 @@ import androidx.compose.material3.BottomSheetScaffoldState import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme @@ -101,11 +106,23 @@ fun CreateScreen( viewModelViewer: ImageViewerViewModel = hiltViewModel(), ) { val isPublishing by viewModelViewer.isPublishing.collectAsState() + val context = LocalContext.current + val galleryLauncher = + rememberLauncherForActivityResult( + contract = ActivityResultContracts.StartActivityForResult(), + ) { result -> + if (result.resultCode == Activity.RESULT_OK) { + val uri = result.data?.data + viewModel.handleImageSelection(uri) + } + } + LaunchedEffect(Unit) { + viewModel.imagePickerLauncher.value = galleryLauncher + } LaunchedEffect(imageUrl) { viewModel.imageUrl = imageUrl } - val bottomSheetState = rememberStandardBottomSheetState( initialValue = SheetValue.Expanded, @@ -367,6 +384,21 @@ private fun CreateScreenContent( ) { InteractiveCanvas(viewModel, graphicsLayer, scale, onScaleChange) } + Box( + modifier = + Modifier + .fillMaxSize() + .padding(bottom = 80.dp, end = 16.dp), + contentAlignment = Alignment.BottomEnd, + ) { + FloatingActionButton( + onClick = { viewModel.pickImageFromGallery() }, + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary, + ) { + Icon(Icons.Default.Add, contentDescription = "Add from gallery") + } + } } @OptIn(ExperimentalMaterial3Api::class) @@ -405,10 +437,23 @@ private fun InteractiveCanvas( val painter = rememberAsyncImagePainter( model = - ImageRequest - .Builder(context) - .data(viewModel.imageUrl) - .build(), + when { + viewModel.imageUrl?.startsWith("content://") == true -> { + // Handle content URI (from gallery) + ImageRequest + .Builder(context) + .data(viewModel.imageUrl) + .build() + } + !viewModel.imageUrl.isNullOrEmpty() -> { + // Handle network URL + ImageRequest + .Builder(context) + .data(viewModel.imageUrl) + .build() + } + else -> null + }, ) // Получаем размеры изображения после загрузки diff --git a/app/src/main/java/com/codekotliners/memify/features/create/presentation/viewmodel/CanvasViewModel.kt b/app/src/main/java/com/codekotliners/memify/features/create/presentation/viewmodel/CanvasViewModel.kt index fffac37d..6247db41 100644 --- a/app/src/main/java/com/codekotliners/memify/features/create/presentation/viewmodel/CanvasViewModel.kt +++ b/app/src/main/java/com/codekotliners/memify/features/create/presentation/viewmodel/CanvasViewModel.kt @@ -1,5 +1,9 @@ package com.codekotliners.memify.features.create.presentation.viewmodel +import android.content.Intent +import android.net.Uri +import android.provider.MediaStore +import androidx.activity.result.ActivityResultLauncher import androidx.compose.runtime.MutableState import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue @@ -49,6 +53,8 @@ open class CanvasViewModel @Inject constructor() : ViewModel() { var imageUrl by mutableStateOf(null) + val imagePickerLauncher = mutableStateOf?>(null) + fun addPointToCurrentLine(point: Offset) { currentLine.add(point) } @@ -132,4 +138,18 @@ open class CanvasViewModel @Inject constructor() : ViewModel() { canvasElements[index] = element.copy(position = newPosition) } } + + fun pickImageFromGallery() { + val intent = + Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI).apply { + type = "image/*" + } + imagePickerLauncher.value?.launch(intent) + } + + fun handleImageSelection(uri: Uri?) { + uri?.let { + imageUrl = it.toString() + } + } }