Start ContactsActivity to edit participants

Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com>
This commit is contained in:
sowjanyakch 2024-08-19 23:48:44 +02:00 committed by Marcel Hibbe
parent 6d0144db1a
commit 6b82d7209f
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
7 changed files with 297 additions and 305 deletions

View File

@ -12,11 +12,15 @@ import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.util.Log
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@ -26,15 +30,20 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.List import androidx.compose.material.icons.automirrored.filled.List
import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -48,6 +57,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
@ -75,21 +85,28 @@ class ContactsActivityCompose : BaseActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
contactsViewModel = ViewModelProvider(this, viewModelFactory)[ContactsViewModel::class.java] contactsViewModel = ViewModelProvider(this, viewModelFactory)[ContactsViewModel::class.java]
val isAddParticipants = intent.getBooleanExtra("isAddParticipants", false)
contactsViewModel.updateIsAddParticipants(isAddParticipants)
if (isAddParticipants) {
contactsViewModel.updateShareTypes(
listOf(
ShareType.Group.shareType,
ShareType.Email.shareType,
ShareType.Circle.shareType
)
)
contactsViewModel.getContactsFromSearchParams()
}
setContent { setContent {
val isAddParticipants = intent.getBooleanExtra("isAddParticipants", false)
val isAddParticipantsEdit = intent.getBooleanExtra("isAddParticipantsEdit", false)
contactsViewModel.updateIsAddParticipants(isAddParticipants)
if (isAddParticipants) {
contactsViewModel.updateShareTypes(
listOf(
ShareType.Group.shareType,
ShareType.Email.shareType,
ShareType.Circle.shareType
)
)
contactsViewModel.getContactsFromSearchParams()
}
val colorScheme = viewThemeUtils.getColorScheme(this) val colorScheme = viewThemeUtils.getColorScheme(this)
val uiState = contactsViewModel.contactsViewState.collectAsState() val uiState = contactsViewModel.contactsViewState.collectAsState()
val selectedParticipants: List<AutocompleteUser> = if (isAddParticipantsEdit) {
intent.getParcelableArrayListExtra("selectedParticipants") ?: emptyList()
} else {
emptyList()
}
contactsViewModel.updateSelectedParticipants(selectedParticipants)
MaterialTheme( MaterialTheme(
colorScheme = colorScheme colorScheme = colorScheme
) { ) {
@ -108,7 +125,8 @@ class ContactsActivityCompose : BaseActivity() {
ContactsList( ContactsList(
contactsUiState = uiState.value, contactsUiState = uiState.value,
contactsViewModel = contactsViewModel, contactsViewModel = contactsViewModel,
context = context context = context,
selectedParticipants = selectedParticipants.toMutableList()
) )
} }
} }
@ -218,13 +236,17 @@ fun AppBar(title: String, context: Context, contactsViewModel: ContactsViewModel
Text( Text(
text = stringResource(id = R.string.nc_contacts_done), text = stringResource(id = R.string.nc_contacts_done),
modifier = Modifier.clickable { modifier = Modifier.clickable {
val selectedParticipants: List<AutocompleteUser> = contactsViewModel.selectedParticipantsList val activity = context as? Activity
val intent = Intent(context, ConversationCreationActivity::class.java) val resultIntent = Intent().apply {
intent.putParcelableArrayListExtra( putParcelableArrayListExtra(
"selectedParticipants", "selectedParticipants",
selectedParticipants as ArrayList<Parcelable> contactsViewModel
) .selectedParticipantsList as
context.startActivity(intent) ArrayList<AutocompleteUser>
)
}
activity?.setResult(Activity.RESULT_OK, resultIntent)
activity?.finish()
} }
) )
} }
@ -304,6 +326,98 @@ fun ConversationCreationOptions(context: Context, contactsViewModel: ContactsVie
} }
} }
@Composable
fun ContactsList(
contactsUiState: ContactsUiState,
contactsViewModel: ContactsViewModel,
context: Context,
selectedParticipants: MutableList<AutocompleteUser>
) {
when (contactsUiState) {
is ContactsUiState.None -> {
}
is ContactsUiState.Loading -> {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CircularProgressIndicator()
}
}
is ContactsUiState.Success -> {
val contacts = contactsUiState.contacts
Log.d(CompanionClass.TAG, "Contacts:$contacts")
if (contacts != null) {
ContactsItem(contacts, contactsViewModel, context, selectedParticipants)
}
}
is ContactsUiState.Error -> {
val errorMessage = contactsUiState.message
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(text = "Error: $errorMessage", color = Color.Red)
}
}
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ContactsItem(
contacts: List<AutocompleteUser>,
contactsViewModel: ContactsViewModel,
context: Context,
selectedParticipants: MutableList<AutocompleteUser>
) {
val groupedContacts: Map<String, List<AutocompleteUser>> = contacts.groupBy { contact ->
(
if (contact.source == "users") {
contact.label?.first()?.uppercase()
} else {
contact.source?.replaceFirstChar { actorType ->
actorType.uppercase()
}
}
).toString()
}
LazyColumn(
modifier = Modifier
.padding(8.dp)
.fillMaxWidth(),
contentPadding = PaddingValues(all = 10.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
) {
groupedContacts.forEach { (initial, contactsForInitial) ->
stickyHeader {
Column {
Surface(Modifier.fillParentMaxWidth()) {
Header(initial)
}
HorizontalDivider(thickness = 0.1.dp, color = Color.Black)
}
}
items(contactsForInitial) { contact ->
ContactItemRow(
contact = contact,
contactsViewModel = contactsViewModel,
context = context,
selectedContacts = selectedParticipants
)
Log.d(CompanionClass.TAG, "Contacts:$contact")
}
}
}
}
@Composable
fun Header(header: String) {
Text(
text = header,
modifier = Modifier
.fillMaxSize()
.background(Color.Transparent)
.padding(start = 60.dp),
color = Color.Blue,
fontWeight = FontWeight.Bold
)
}
class CompanionClass { class CompanionClass {
companion object { companion object {
internal val TAG = ContactsActivityCompose::class.simpleName internal val TAG = ContactsActivityCompose::class.simpleName

View File

@ -31,7 +31,7 @@ class ContactsViewModel @Inject constructor(
private val _searchState = MutableStateFlow(false) private val _searchState = MutableStateFlow(false)
val searchState: StateFlow<Boolean> = _searchState val searchState: StateFlow<Boolean> = _searchState
private val selectedParticipants = mutableListOf<AutocompleteUser>() private val selectedParticipants = mutableListOf<AutocompleteUser>()
val selectedParticipantsList: List<AutocompleteUser> = selectedParticipants val selectedParticipantsList: MutableList<AutocompleteUser> = selectedParticipants
private val _isAddParticipantsView = MutableStateFlow(false) private val _isAddParticipantsView = MutableStateFlow(false)
val isAddParticipantsView: StateFlow<Boolean> = _isAddParticipantsView val isAddParticipantsView: StateFlow<Boolean> = _isAddParticipantsView

View File

@ -1,118 +0,0 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.contacts
import android.content.Context
import android.util.Log
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
@Composable
fun ContactsList(contactsUiState: ContactsUiState, contactsViewModel: ContactsViewModel, context: Context) {
when (contactsUiState) {
is ContactsUiState.None -> {
}
is ContactsUiState.Loading -> {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CircularProgressIndicator()
}
}
is ContactsUiState.Success -> {
val contacts = contactsUiState.contacts
Log.d(CompanionClass.TAG, "Contacts:$contacts")
if (contacts != null) {
ContactsItem(contacts, contactsViewModel, context)
}
}
is ContactsUiState.Error -> {
val errorMessage = contactsUiState.message
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(text = "Error: $errorMessage", color = Color.Red)
}
}
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ContactsItem(contacts: List<AutocompleteUser>, contactsViewModel: ContactsViewModel, context: Context) {
val groupedContacts: Map<String, List<AutocompleteUser>> = contacts.groupBy { contact ->
(
if (contact.source == "users") {
contact.label?.first()?.uppercase()
} else {
contact.source?.replaceFirstChar { actorType ->
actorType.uppercase()
}
}
).toString()
}
val selectedContacts = remember { mutableStateListOf<AutocompleteUser>() }
LazyColumn(
modifier = Modifier
.padding(8.dp)
.fillMaxWidth(),
contentPadding = PaddingValues(all = 10.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
) {
groupedContacts.forEach { (initial, contactsForInitial) ->
stickyHeader {
Column {
Surface(Modifier.fillParentMaxWidth()) {
Header(initial)
}
HorizontalDivider(thickness = 0.1.dp, color = Color.Black)
}
}
items(contactsForInitial) { contact ->
ContactItemRow(
contact = contact,
contactsViewModel = contactsViewModel,
context = context,
selectedContacts = selectedContacts
)
Log.d(CompanionClass.TAG, "Contacts:$contact")
}
}
}
}
@Composable
fun Header(header: String) {
Text(
text = header,
modifier = Modifier
.fillMaxSize()
.background(Color.Transparent)
.padding(start = 60.dp),
color = Color.Blue,
fontWeight = FontWeight.Bold
)
}

View File

@ -7,24 +7,29 @@
package com.nextcloud.talk.conversationcreation package com.nextcloud.talk.conversationcreation
import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Button import androidx.compose.material3.Button
@ -56,6 +61,7 @@ import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.contacts.ContactsActivityCompose import com.nextcloud.talk.contacts.ContactsActivityCompose
import com.nextcloud.talk.contacts.loadImage
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
import javax.inject.Inject import javax.inject.Inject
@ -63,60 +69,76 @@ import javax.inject.Inject
class ConversationCreationActivity : BaseActivity() { class ConversationCreationActivity : BaseActivity() {
@Inject @Inject
lateinit var viewModelFactory: ViewModelProvider.Factory lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var conversationCreationViewModel: ConversationCreationViewModel
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
conversationCreationViewModel =
ViewModelProvider(this, viewModelFactory)[ConversationCreationViewModel::class.java]
val selectedParticipants: List<AutocompleteUser>? = when (
Build.VERSION.SDK_INT >= Build.VERSION_CODES
.TIRAMISU
) {
true -> intent.getParcelableArrayListExtra("selectedParticipants")
else -> intent.extras?.getParcelableArrayList("selectedParticipants")
} ?: emptyList()
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
val conversationCreationViewModel = ViewModelProvider(
this,
viewModelFactory
)[ConversationCreationViewModel::class.java]
setContent { setContent {
val colorScheme = viewThemeUtils.getColorScheme(this) val colorScheme = viewThemeUtils.getColorScheme(this)
MaterialTheme( MaterialTheme(
colorScheme = colorScheme colorScheme = colorScheme
) { ) {
val context = LocalContext.current ConversationCreationScreen(conversationCreationViewModel)
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = stringResource(id = R.string.nc_new_conversation)) },
navigationIcon = {
IconButton(onClick = {
(context as? Activity)?.finish()
}) {
Icon(
Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(R.string.back_button)
)
}
}
)
},
content = {
Column(Modifier.padding(it)) {
DefaultUserAvatar()
UploadAvatar()
ConversationNameAndDescription(conversationCreationViewModel)
AddParticipants(selectedParticipants, context)
RoomCreationOptions(conversationCreationViewModel)
CreateConversation()
}
}
)
} }
} }
} }
} }
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ConversationCreationScreen(conversationCreationViewModel: ConversationCreationViewModel) {
val context = LocalContext.current
val launcher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult(),
onResult = { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data = result.data
val selectedParticipants = data?.getParcelableArrayListExtra<AutocompleteUser>("selectedParticipants")
?: emptyList()
conversationCreationViewModel.updateSelectedParticipants(selectedParticipants)
}
}
)
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = stringResource(id = R.string.nc_new_conversation)) },
navigationIcon = {
IconButton(onClick = {
(context as? Activity)?.finish()
}) {
Icon(
Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(id = R.string.back_button)
)
}
}
)
},
content = { paddingValues ->
Column(
modifier = Modifier
.padding(paddingValues)
.verticalScroll(rememberScrollState())
) {
DefaultUserAvatar()
UploadAvatar()
ConversationNameAndDescription(conversationCreationViewModel)
AddParticipants(launcher, context, conversationCreationViewModel)
RoomCreationOptions(conversationCreationViewModel)
CreateConversation()
}
}
)
}
@Composable @Composable
fun DefaultUserAvatar() { fun DefaultUserAvatar() {
Box( Box(
@ -196,7 +218,7 @@ fun ConversationNameAndDescription(conversationCreationViewModel: ConversationCr
OutlinedTextField( OutlinedTextField(
value = conversationDescription.value, value = conversationDescription.value,
onValueChange = { onValueChange = {
conversationCreationViewModel.updateRoomName(it) conversationCreationViewModel.updateConversationDescription(it)
}, },
label = { Text(text = stringResource(id = R.string.nc_conversation_description)) }, label = { Text(text = stringResource(id = R.string.nc_conversation_description)) },
modifier = Modifier modifier = Modifier
@ -205,59 +227,88 @@ fun ConversationNameAndDescription(conversationCreationViewModel: ConversationCr
) )
} }
@SuppressLint("SuspiciousIndentation")
@Composable @Composable
fun AddParticipants(selectedParticipants: List<AutocompleteUser>?, context: Context) { fun AddParticipants(
Row { launcher: ManagedActivityResultLauncher<Intent, ActivityResult>,
Text( context: Context,
text = stringResource(id = R.string.nc_participants).uppercase(), conversationCreationViewModel: ConversationCreationViewModel
fontSize = 14.sp, ) {
modifier = Modifier.padding(top = 24.dp, start = 16.dp, end = 16.dp, bottom = 16.dp) val participants = conversationCreationViewModel.selectedParticipants.collectAsState()
)
if (selectedParticipants?.isNotEmpty() == true) {
Text(
text = stringResource(id = R.string.nc_edit),
fontSize = 12.sp,
modifier = Modifier.padding(top = 24.dp, start = 16.dp, end = 16.dp, bottom = 16.dp)
.clickable {
val intent = Intent(context, ContactsActivityCompose::class.java)
context.startActivity(intent)
},
textAlign = TextAlign.Right
)
}
}
Row( Column(
modifier = Modifier modifier = Modifier.fillMaxHeight()
.padding(start = 16.dp, end = 16.dp) .padding(start = 16.dp, end = 16.dp, top = 16.dp)
.clickable {
val intent = Intent(context, ContactsActivityCompose::class.java)
intent.putExtra("isAddParticipants", true)
context.startActivity(intent)
},
verticalAlignment = Alignment
.CenterVertically
) { ) {
if (selectedParticipants?.isEmpty() == true) { Row {
Icon( Text(
painter = painterResource(id = R.drawable.ic_account_plus), text = stringResource(id = R.string.nc_participants).uppercase(),
contentDescription = null, fontSize = 14.sp,
modifier = Modifier.size(24.dp) modifier = Modifier.padding(start = 16.dp, bottom = 16.dp)
) )
Spacer(modifier = Modifier.weight(1f))
if (participants.value.isNotEmpty()) {
Text(
text = stringResource(id = R.string.nc_edit),
fontSize = 12.sp,
modifier = Modifier
.padding(start = 16.dp, bottom = 16.dp)
.clickable {
val intent = Intent(context, ContactsActivityCompose::class.java)
intent.putParcelableArrayListExtra(
"selected participants",
participants.value as ArrayList<AutocompleteUser>
)
intent.putExtra("isAddParticipantsEdit", true)
launcher.launch(intent)
},
textAlign = TextAlign.Right
)
}
}
Text(text = stringResource(id = R.string.nc_add_participants), modifier = Modifier.padding(start = 16.dp)) participants.value.forEach { participant ->
} else { Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
LazyColumn { val imageUri = participant.id?.let { conversationCreationViewModel.getImageUri(it, true) }
items(selectedParticipants!!) { participant -> val errorPlaceholderImage: Int = R.drawable.account_circle_96dp
participant.label?.let { val loadedImage = loadImage(imageUri, context, errorPlaceholderImage)
Text( AsyncImage(
text = it, model = loadedImage,
modifier = Modifier.padding(all = 16.dp) contentDescription = stringResource(id = R.string.user_avatar),
) modifier = Modifier.size(width = 32.dp, height = 32.dp)
} )
HorizontalDivider(thickness = 0.1.dp, color = Color.Black) participant.label?.let {
Text(
text = it,
modifier = Modifier.padding(all = 16.dp),
fontSize = 15.sp
)
} }
} }
HorizontalDivider(thickness = 0.1.dp, color = Color.Black)
}
Row(
modifier = Modifier
.fillMaxWidth()
.clickable {
val intent = Intent(context, ContactsActivityCompose::class.java)
intent.putExtra("isAddParticipants", true)
launcher.launch(intent)
},
verticalAlignment = Alignment.CenterVertically
) {
if (participants.value.isEmpty()) {
Icon(
painter = painterResource(id = R.drawable.ic_account_plus),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
Text(
text = stringResource(id = R.string.nc_add_participants),
modifier = Modifier.padding(start = 16.dp)
)
}
} }
} }
} }
@ -366,78 +417,3 @@ fun CreateConversation() {
} }
} }
} }
//
// @SuppressLint("UnrememberedMutableState")
// @OptIn(ExperimentalMaterial3Api::class)
// @Composable
// fun AppBar(title: String, context: Context, contactsViewModel: ContactsViewModel) {
// val searchQuery by contactsViewModel.searchQuery.collectAsState()
// val searchState = contactsViewModel.searchState.collectAsState()
// val addParticipantsUiState = contactsViewModel.addParticipantsUiState.collectAsState()
// val conversationToken:String? = null
//
// TopAppBar(
// title = { Text(text = title) },
// navigationIcon = {
// IconButton(onClick = {
// (context as? Activity)?.finish()
// }) {
// Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.back_button))
// }
// },
// actions = {
// IconButton(onClick = {
// contactsViewModel.updateSearchState(true)
// }) {
// Icon(Icons.Filled.Search, contentDescription = stringResource(R.string.search_icon))
// }
// if (contactsViewModel.isAddParticipantsView.value) {
// Text(
// text = stringResource(id = R.string.nc_contacts_done),
// modifier = Modifier.clickable {
// for(contacts in contactsViewModel.selectedParticipantsList){
// contacts.let { contact ->
// contactsViewModel.addParticipants(
// conversationToken,
// contact.id!!,
// contact.source!!
// )
// }
// }
// }
// )
// }
// }
// )
// val state = addParticipantsUiState.value
// when(state){
// is AddParticipantsUiState.Error -> {
// val errorMessage = state.message
// Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
// Text(text = "Error: $errorMessage", color = Color.Red)
// }
//
// }
// is AddParticipantsUiState.None -> {
//
//
// }
// is AddParticipantsUiState.Success -> {
// val conversation = state.participants
// Log.d("ContactsActivityCompose", "$conversation")
// }
// }
// if (searchState.value) {
// Row {
// DisplaySearch(
// text = searchQuery,
// onTextChange = { searchQuery ->
// contactsViewModel.updateSearchQuery(query = searchQuery)
// contactsViewModel.getContactsFromSearchParams()
// },
// contactsViewModel = contactsViewModel
// )
// }
// }
// }

View File

@ -14,4 +14,5 @@ interface ConversationCreationRepository {
suspend fun renameConversation(roomToken: String, roomNameNew: String?): GenericOverall suspend fun renameConversation(roomToken: String, roomNameNew: String?): GenericOverall
suspend fun setConversationDescription(roomToken: String, description: String?): GenericOverall suspend fun setConversationDescription(roomToken: String, description: String?): GenericOverall
suspend fun addParticipants(conversationToken: String?, userId: String, sourceType: String): AddParticipantOverall suspend fun addParticipants(conversationToken: String?, userId: String, sourceType: String): AddParticipantOverall
fun getImageUri(avatarId: String, requestBigSize: Boolean): String
} }

View File

@ -73,4 +73,12 @@ class ConversationCreationRepositoryImpl(
} }
return ncApiCoroutines.addParticipant(credentials, retrofitBucket.url, retrofitBucket.queryMap) return ncApiCoroutines.addParticipant(credentials, retrofitBucket.url, retrofitBucket.queryMap)
} }
override fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
return ApiUtils.getUrlForAvatar(
_currentUser.baseUrl,
avatarId,
requestBigSize
)
}
} }

View File

@ -12,6 +12,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.nextcloud.talk.contacts.AddParticipantsUiState import com.nextcloud.talk.contacts.AddParticipantsUiState
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -20,6 +21,12 @@ import javax.inject.Inject
class ConversationCreationViewModel @Inject constructor( class ConversationCreationViewModel @Inject constructor(
private val repository: ConversationCreationRepository private val repository: ConversationCreationRepository
) : ViewModel() { ) : ViewModel() {
private val _selectedParticipants = MutableStateFlow<List<AutocompleteUser>>(emptyList())
val selectedParticipants: StateFlow<List<AutocompleteUser>> = _selectedParticipants
fun updateSelectedParticipants(participants: List<AutocompleteUser>) {
_selectedParticipants.value = participants
}
private val _roomName = MutableStateFlow("") private val _roomName = MutableStateFlow("")
val roomName: StateFlow<String> = _roomName val roomName: StateFlow<String> = _roomName
@ -69,4 +76,8 @@ class ConversationCreationViewModel @Inject constructor(
} }
} }
} }
fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
return repository.getImageUri(avatarId, requestBigSize)
}
} }