diff --git a/app/src/main/java/com/nextcloud/talk/conversationcreation/ConversationCreationActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationcreation/ConversationCreationActivity.kt index 021f6e9cf..e2bf8e5ea 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationcreation/ConversationCreationActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationcreation/ConversationCreationActivity.kt @@ -13,6 +13,7 @@ import android.annotation.SuppressLint import android.app.Activity import android.content.Context import android.content.Intent +import android.net.Uri import android.os.Bundle import androidx.activity.compose.ManagedActivityResultLauncher import androidx.activity.compose.rememberLauncherForActivityResult @@ -77,6 +78,7 @@ import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.contacts.ContactsActivityCompose import com.nextcloud.talk.contacts.loadImage import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser +import com.nextcloud.talk.utils.PickImage import com.nextcloud.talk.utils.bundle.BundleKeys import javax.inject.Inject @@ -84,7 +86,7 @@ import javax.inject.Inject class ConversationCreationActivity : BaseActivity() { @Inject lateinit var viewModelFactory: ViewModelProvider.Factory - + private lateinit var pickImage: PickImage override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -93,13 +95,16 @@ class ConversationCreationActivity : BaseActivity() { this, viewModelFactory )[ConversationCreationViewModel::class.java] + val conversationUser = conversationCreationViewModel.currentUser + pickImage = PickImage(this, conversationUser) + setContent { val colorScheme = viewThemeUtils.getColorScheme(this) val context = LocalContext.current MaterialTheme( colorScheme = colorScheme ) { - ConversationCreationScreen(conversationCreationViewModel, context) + ConversationCreationScreen(conversationCreationViewModel, context, pickImage) } SetStatusBarColor() } @@ -125,15 +130,47 @@ private fun SetStatusBarColor() { @OptIn(ExperimentalMaterial3Api::class) @Composable -fun ConversationCreationScreen(conversationCreationViewModel: ConversationCreationViewModel, context: Context) { +fun ConversationCreationScreen( + conversationCreationViewModel: ConversationCreationViewModel, + context: Context, + pickImage: PickImage +) { + var selectedImageUri by remember { mutableStateOf(null) } + + val imagePickerLauncher = rememberLauncherForActivityResult( + contract = ActivityResultContracts.StartActivityForResult() + ) { result -> + if (result.resultCode == Activity.RESULT_OK) { + pickImage.onImagePickerResult(result.data) { uri -> + selectedImageUri = uri + } + } + } + + val remoteFilePickerLauncher = rememberLauncherForActivityResult( + contract = ActivityResultContracts.StartActivityForResult() + ) { result -> + if (result.resultCode == Activity.RESULT_OK) { + pickImage.onSelectRemoteFilesResult(imagePickerLauncher, result.data) + } + } + + val cameraLauncher = rememberLauncherForActivityResult( + contract = ActivityResultContracts.StartActivityForResult() + ) { result -> + if (result.resultCode == Activity.RESULT_OK) { + pickImage.onTakePictureResult(imagePickerLauncher, result.data) + } + } + val launcher = rememberLauncherForActivityResult( contract = ActivityResultContracts.StartActivityForResult(), - onResult = { result -> if (result.resultCode == Activity.RESULT_OK) { val data = result.data - val selectedParticipants = data?.getParcelableArrayListExtra("selectedParticipants") - ?: emptyList() + val selectedParticipants = + data?.getParcelableArrayListExtra("selectedParticipants") + ?: emptyList() val participants = selectedParticipants.toMutableList() conversationCreationViewModel.updateSelectedParticipants(participants) } @@ -162,8 +199,16 @@ fun ConversationCreationScreen(conversationCreationViewModel: ConversationCreati .padding(paddingValues) .verticalScroll(rememberScrollState()) ) { - DefaultUserAvatar() - UploadAvatar() + DefaultUserAvatar(selectedImageUri) + UploadAvatar( + pickImage = pickImage, + onImageSelected = { uri -> selectedImageUri = uri }, + imagePickerLauncher = imagePickerLauncher, + remoteFilePickerLauncher = remoteFilePickerLauncher, + cameraLauncher = cameraLauncher, + onDeleteImage = { selectedImageUri = null } + ) + ConversationNameAndDescription(conversationCreationViewModel) AddParticipants(launcher, context, conversationCreationViewModel) RoomCreationOptions(conversationCreationViewModel) @@ -174,31 +219,51 @@ fun ConversationCreationScreen(conversationCreationViewModel: ConversationCreati } @Composable -fun DefaultUserAvatar() { +fun DefaultUserAvatar(selectedImageUri: Uri?) { Box( modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center ) { - AsyncImage( - model = R.drawable.ic_circular_group, - contentDescription = stringResource(id = R.string.user_avatar), - modifier = Modifier - .size(width = 84.dp, height = 84.dp) - .padding(top = 8.dp) - ) + if (selectedImageUri != null) { + AsyncImage( + model = selectedImageUri, + contentDescription = stringResource(id = R.string.user_avatar), + modifier = Modifier + .size(84.dp) + .padding(top = 8.dp) + ) + } else { + AsyncImage( + model = R.drawable.ic_circular_group, + contentDescription = stringResource(id = R.string.user_avatar), + modifier = Modifier + .size(84.dp) + .padding(top = 8.dp) + ) + } } } @Composable -fun UploadAvatar() { +fun UploadAvatar( + pickImage: PickImage, + onImageSelected: (Uri) -> Unit, + imagePickerLauncher: ManagedActivityResultLauncher, + remoteFilePickerLauncher: ManagedActivityResultLauncher, + cameraLauncher: ManagedActivityResultLauncher, + onDeleteImage: () -> Unit +) { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), horizontalArrangement = Arrangement.Center ) { - IconButton(onClick = { - }) { + IconButton( + onClick = { + pickImage.takePicture(cameraLauncher) + } + ) { Icon( painter = painterResource(id = R.drawable.ic_baseline_photo_camera_24), contentDescription = null, @@ -207,6 +272,7 @@ fun UploadAvatar() { } IconButton(onClick = { + pickImage.selectLocal(imagePickerLauncher) }) { Icon( painter = painterResource(id = R.drawable.ic_folder_multiple_image), @@ -214,9 +280,11 @@ fun UploadAvatar() { modifier = Modifier.size(24.dp) ) } - - IconButton(onClick = { - }) { + IconButton( + onClick = { + pickImage.selectRemote(remoteFilePickerLauncher) + } + ) { Icon( painter = painterResource(id = R.drawable.baseline_tag_faces_24), contentDescription = null, @@ -225,6 +293,7 @@ fun UploadAvatar() { } IconButton(onClick = { + onDeleteImage() }) { Icon( painter = painterResource(id = R.drawable.ic_delete_grey600_24dp), @@ -530,6 +599,7 @@ fun CreateConversation(conversationCreationViewModel: ConversationCreationViewMo } } } + class CompanionClass { companion object { internal val TAG = ConversationCreationActivity::class.simpleName diff --git a/app/src/main/java/com/nextcloud/talk/conversationcreation/ConversationCreationViewModel.kt b/app/src/main/java/com/nextcloud/talk/conversationcreation/ConversationCreationViewModel.kt index 2b9213383..e710b3b3e 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationcreation/ConversationCreationViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationcreation/ConversationCreationViewModel.kt @@ -11,11 +11,13 @@ import android.util.Log import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.models.domain.ConversationModel import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.generic.GenericMeta import com.nextcloud.talk.repositories.conversations.ConversationsRepositoryImpl.Companion.STATUS_CODE_OK +import com.nextcloud.talk.users.UserManager import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch @@ -23,7 +25,8 @@ import java.io.File import javax.inject.Inject class ConversationCreationViewModel @Inject constructor( - private val repository: ConversationCreationRepository + private val repository: ConversationCreationRepository, + private val userManager: UserManager ) : ViewModel() { private val _selectedParticipants = MutableStateFlow>(emptyList()) val selectedParticipants: StateFlow> = _selectedParticipants @@ -35,6 +38,9 @@ class ConversationCreationViewModel @Inject constructor( private val _deleteState = MutableStateFlow(DeleteAvatarState.Loading) val deleteState: StateFlow = _deleteState + private val _currentUser = userManager.currentUser.blockingGet() + val currentUser: User = _currentUser + fun updateSelectedParticipants(participants: List) { _selectedParticipants.value = participants }