add isAddParticipant flag

Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com>
This commit is contained in:
sowjanyakch 2024-08-06 23:21:36 +02:00 committed by Marcel Hibbe
parent d32bc74559
commit 9f61793c86
No known key found for this signature in database
GPG key ID: C793F8B59F43CE7B
5 changed files with 192 additions and 147 deletions

View file

@ -12,15 +12,10 @@ 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.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.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@ -29,20 +24,15 @@ 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
@ -54,7 +44,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext 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.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
@ -82,6 +71,8 @@ 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)
setContent { setContent {
val colorScheme = viewThemeUtils.getColorScheme(this) val colorScheme = viewThemeUtils.getColorScheme(this)
val uiState = contactsViewModel.contactsViewState.collectAsState() val uiState = contactsViewModel.contactsViewState.collectAsState()
@ -99,7 +90,7 @@ class ContactsActivityCompose : BaseActivity() {
}, },
content = { content = {
Column(Modifier.padding(it)) { Column(Modifier.padding(it)) {
ConversationCreationOptions(context = context) ConversationCreationOptions(context = context, contactsViewModel = contactsViewModel)
ContactsList( ContactsList(
contactsUiState = uiState.value, contactsUiState = uiState.value,
contactsViewModel = contactsViewModel, contactsViewModel = contactsViewModel,
@ -110,87 +101,9 @@ class ContactsActivityCompose : BaseActivity() {
) )
} }
} }
setupSystemColors()
} }
} }
@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 = MaterialTheme.colorScheme.error)
}
}
}
}
@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()
}
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 = 1.dp, color = MaterialTheme.colorScheme.outlineVariant)
}
}
items(contactsForInitial) { contact ->
ContactItemRow(contact = contact, contactsViewModel = contactsViewModel, context = context)
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 = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.Bold
)
}
@Composable @Composable
fun ContactItemRow(contact: AutocompleteUser, contactsViewModel: ContactsViewModel, context: Context) { fun ContactItemRow(contact: AutocompleteUser, contactsViewModel: ContactsViewModel, context: Context) {
val roomUiState by contactsViewModel.roomViewState.collectAsState() val roomUiState by contactsViewModel.roomViewState.collectAsState()
@ -231,7 +144,7 @@ fun ContactItemRow(contact: AutocompleteUser, contactsViewModel: ContactsViewMod
is RoomUiState.Error -> { is RoomUiState.Error -> {
val errorMessage = (roomUiState as RoomUiState.Error).message val errorMessage = (roomUiState as RoomUiState.Error).message
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(text = "Error: $errorMessage", color = MaterialTheme.colorScheme.error) Text(text = "Error: $errorMessage", color = Color.Red)
} }
} }
is RoomUiState.None -> {} is RoomUiState.None -> {}
@ -276,10 +189,13 @@ fun AppBar(title: String, context: Context, contactsViewModel: ContactsViewModel
} }
@Composable @Composable
fun ConversationCreationOptions(context: Context) { fun ConversationCreationOptions(context: Context, contactsViewModel: ContactsViewModel) {
val isAddParticipants by contactsViewModel.isAddParticipantsView.collectAsState()
if (!isAddParticipants) {
Column { Column {
Row( Row(
modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp) modifier = Modifier
.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp)
.clickable { .clickable {
val intent = Intent(context, ConversationCreationActivity::class.java) val intent = Intent(context, ConversationCreationActivity::class.java)
context.startActivity(intent) context.startActivity(intent)
@ -330,6 +246,7 @@ fun ConversationCreationOptions(context: Context) {
} }
} }
} }
}

View file

@ -30,6 +30,8 @@ class ContactsViewModel @Inject constructor(
val shareTypeList: List<String> = shareTypes val shareTypeList: List<String> = shareTypes
private val _searchState = MutableStateFlow(false) private val _searchState = MutableStateFlow(false)
val searchState: StateFlow<Boolean> = _searchState val searchState: StateFlow<Boolean> = _searchState
private val _isAddParticipantsView = MutableStateFlow(false)
val isAddParticipantsView: StateFlow<Boolean> = _isAddParticipantsView
init { init {
getContactsFromSearchParams() getContactsFromSearchParams()
@ -47,6 +49,10 @@ class ContactsViewModel @Inject constructor(
shareTypes.add(value) shareTypes.add(value)
} }
fun updateIsAddParticipants(value: Boolean) {
_isAddParticipantsView.value = value
}
fun getContactsFromSearchParams() { fun getContactsFromSearchParams() {
_contactsViewState.value = ContactsUiState.Loading _contactsViewState.value = ContactsUiState.Loading
viewModelScope.launch { viewModelScope.launch {

View file

@ -0,0 +1,110 @@
/*
* 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.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()
}
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)
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

@ -14,11 +14,13 @@ import androidx.compose.foundation.text.KeyboardOptions
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.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Button
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextField import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -30,6 +32,7 @@ import com.nextcloud.talk.R
@Composable @Composable
fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewModel: ContactsViewModel) { fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewModel: ContactsViewModel) {
val isAddParticipants = contactsViewModel.isAddParticipantsView.collectAsState()
val keyboardController = LocalSoftwareKeyboardController.current val keyboardController = LocalSoftwareKeyboardController.current
TextField( TextField(
modifier = Modifier modifier = Modifier
@ -42,7 +45,6 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode
text = stringResource(R.string.nc_search) text = stringResource(R.string.nc_search)
) )
}, },
textStyle = TextStyle( textStyle = TextStyle(
fontSize = 16.sp fontSize = 16.sp
), ),
@ -91,4 +93,10 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode
), ),
maxLines = 1 maxLines = 1
) )
if (isAddParticipants.value) {
Button(onClick = {
}, modifier = Modifier.fillMaxWidth(0.2f)) {
Text(text = "Done")
}
}
} }

View file

@ -8,6 +8,8 @@
package com.nextcloud.talk.conversationcreation package com.nextcloud.talk.conversationcreation
import android.app.Activity import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -46,6 +48,7 @@ import coil.compose.AsyncImage
import com.nextcloud.talk.R 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.ContactsViewModel import com.nextcloud.talk.contacts.ContactsViewModel
import javax.inject.Inject import javax.inject.Inject
@ -54,7 +57,6 @@ class ConversationCreationActivity : BaseActivity() {
@Inject @Inject
lateinit var viewModelFactory: ViewModelProvider.Factory lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var conversationCreationViewModel: ConversationCreationViewModel private lateinit var conversationCreationViewModel: ConversationCreationViewModel
private lateinit var contactsViewModel: ContactsViewModel
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -62,7 +64,8 @@ class ConversationCreationActivity : BaseActivity() {
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
conversationCreationViewModel = conversationCreationViewModel =
ViewModelProvider(this, viewModelFactory)[ConversationCreationViewModel::class.java] ViewModelProvider(this, viewModelFactory)[ConversationCreationViewModel::class.java]
contactsViewModel = ViewModelProvider(this, viewModelFactory)[ContactsViewModel::class.java] val contactsViewModel = ViewModelProvider(this, viewModelFactory)[ContactsViewModel::class.java]
setContent { setContent {
val colorScheme = viewThemeUtils.getColorScheme(this) val colorScheme = viewThemeUtils.getColorScheme(this)
MaterialTheme( MaterialTheme(
@ -73,7 +76,6 @@ class ConversationCreationActivity : BaseActivity() {
topBar = { topBar = {
TopAppBar( TopAppBar(
title = { Text(text = stringResource(id = R.string.nc_new_conversation)) }, title = { Text(text = stringResource(id = R.string.nc_new_conversation)) },
navigationIcon = { navigationIcon = {
IconButton(onClick = { IconButton(onClick = {
(context as? Activity)?.finish() (context as? Activity)?.finish()
@ -91,7 +93,7 @@ class ConversationCreationActivity : BaseActivity() {
DefaultUserAvatar() DefaultUserAvatar()
UploadAvatar() UploadAvatar()
ConversationNameAndDescription(conversationCreationViewModel) ConversationNameAndDescription(conversationCreationViewModel)
AddParticipants(contactsViewModel) AddParticipants(contactsViewModel, context)
RoomCreationOptions(conversationCreationViewModel) RoomCreationOptions(conversationCreationViewModel)
} }
} }
@ -190,7 +192,7 @@ fun ConversationNameAndDescription(conversationCreationViewModel: ConversationCr
} }
@Composable @Composable
fun AddParticipants(contactsViewModel: ContactsViewModel) { fun AddParticipants(contactsViewModel: ContactsViewModel, context: Context) {
Text( Text(
text = stringResource(id = R.string.nc_participants).uppercase(), text = stringResource(id = R.string.nc_participants).uppercase(),
fontSize = 14.sp, fontSize = 14.sp,
@ -201,7 +203,9 @@ fun AddParticipants(contactsViewModel: ContactsViewModel) {
modifier = Modifier modifier = Modifier
.padding(start = 16.dp, end = 16.dp) .padding(start = 16.dp, end = 16.dp)
.clickable { .clickable {
// Show contacts val intent = Intent(context, ContactsActivityCompose::class.java)
intent.putExtra("isAddParticipants", true)
context.startActivity(intent)
}, },
verticalAlignment = Alignment verticalAlignment = Alignment
.CenterVertically .CenterVertically