Merge pull request #4182 from nextcloud/select_search_contacts

Select contacts from search
This commit is contained in:
Marcel Hibbe 2024-09-11 10:02:39 +02:00 committed by GitHub
commit 14752c6ec4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 175 additions and 110 deletions

View File

@ -1,6 +1,30 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="ktlint" /> <option name="myName" value="ktlint" />
<inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="KotlinUnusedImport" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="KotlinUnusedImport" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />

View File

@ -2546,19 +2546,14 @@ class ChatActivity :
private fun isScrolledToBottom() = layoutManager?.findFirstVisibleItemPosition() == 0 private fun isScrolledToBottom() = layoutManager?.findFirstVisibleItemPosition() == 0
private fun shouldInsertNewMessagesNotice( private fun shouldInsertNewMessagesNotice(newMessagesAvailable: Boolean, chatMessageList: List<ChatMessage>) =
newMessagesAvailable: Boolean, if (newMessagesAvailable) {
chatMessageList: List<ChatMessage> chatMessageList.any { it.actorId != conversationUser!!.userId }
) = if (newMessagesAvailable) { } else {
chatMessageList.any { it.actorId != conversationUser!!.userId } false
} else { }
false
}
private fun updateUnreadMessageInfos( private fun updateUnreadMessageInfos(chatMessageList: List<ChatMessage>, scrollToEndOnUpdate: Boolean) {
chatMessageList: List<ChatMessage>,
scrollToEndOnUpdate: Boolean
) {
val unreadChatMessage = ChatMessage() val unreadChatMessage = ChatMessage()
unreadChatMessage.jsonMessageId = -1 unreadChatMessage.jsonMessageId = -1
unreadChatMessage.actorId = "-1" unreadChatMessage.actorId = "-1"

View File

@ -116,9 +116,9 @@ class ContactsActivityCompose : BaseActivity() {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
intent.getParcelableArrayListExtra("selectedParticipants") ?: emptyList() intent.getParcelableArrayListExtra("selectedParticipants") ?: emptyList()
} }
} }.toSet().toMutableList()
val participants = selectedParticipants.toSet().toMutableList() contactsViewModel.updateSelectedParticipants(selectedParticipants)
contactsViewModel.updateSelectedParticipants(participants)
MaterialTheme( MaterialTheme(
colorScheme = colorScheme colorScheme = colorScheme
) { ) {
@ -137,8 +137,7 @@ class ContactsActivityCompose : BaseActivity() {
ContactsList( ContactsList(
contactsUiState = uiState.value, contactsUiState = uiState.value,
contactsViewModel = contactsViewModel, contactsViewModel = contactsViewModel,
context = context, context = context
selectedParticipants = selectedParticipants.toMutableList()
) )
} }
} }
@ -168,13 +167,8 @@ class ContactsActivityCompose : BaseActivity() {
} }
@Composable @Composable
fun ContactItemRow( fun ContactItemRow(contact: AutocompleteUser, contactsViewModel: ContactsViewModel, context: Context) {
contact: AutocompleteUser, var isSelected by remember { mutableStateOf(contactsViewModel.selectedParticipantsList.value.contains(contact)) }
contactsViewModel: ContactsViewModel,
context: Context,
selectedContacts: MutableList<AutocompleteUser>
) {
var isSelected by remember { mutableStateOf(selectedContacts.contains(contact)) }
val roomUiState by contactsViewModel.roomViewState.collectAsState() val roomUiState by contactsViewModel.roomViewState.collectAsState()
val isAddParticipants = contactsViewModel.isAddParticipantsView.collectAsState() val isAddParticipants = contactsViewModel.isAddParticipantsView.collectAsState()
Row( Row(
@ -191,14 +185,11 @@ fun ContactItemRow(
) )
} else { } else {
isSelected = !isSelected isSelected = !isSelected
selectedContacts.apply { if (isSelected) {
if (isSelected) { contactsViewModel.selectContact(contact)
add(contact) } else {
} else { contactsViewModel.deselectContact(contact)
remove(contact)
}
} }
contactsViewModel.updateSelectedParticipants(selectedContacts)
} }
} }
), ),
@ -363,12 +354,7 @@ fun ConversationCreationOptions(context: Context, contactsViewModel: ContactsVie
} }
@Composable @Composable
fun ContactsList( fun ContactsList(contactsUiState: ContactsUiState, contactsViewModel: ContactsViewModel, context: Context) {
contactsUiState: ContactsUiState,
contactsViewModel: ContactsViewModel,
context: Context,
selectedParticipants: MutableList<AutocompleteUser>
) {
when (contactsUiState) { when (contactsUiState) {
is ContactsUiState.None -> { is ContactsUiState.None -> {
} }
@ -381,7 +367,7 @@ fun ContactsList(
val contacts = contactsUiState.contacts val contacts = contactsUiState.contacts
Log.d(CompanionClass.TAG, "Contacts:$contacts") Log.d(CompanionClass.TAG, "Contacts:$contacts")
if (contacts != null) { if (contacts != null) {
ContactsItem(contacts, contactsViewModel, context, selectedParticipants) ContactsItem(contacts, contactsViewModel, context)
} }
} }
is ContactsUiState.Error -> { is ContactsUiState.Error -> {
@ -395,12 +381,7 @@ fun ContactsList(
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun ContactsItem( fun ContactsItem(contacts: List<AutocompleteUser>, contactsViewModel: ContactsViewModel, context: Context) {
contacts: List<AutocompleteUser>,
contactsViewModel: ContactsViewModel,
context: Context,
selectedParticipants: MutableList<AutocompleteUser>
) {
val groupedContacts: Map<String, List<AutocompleteUser>> = contacts.groupBy { contact -> val groupedContacts: Map<String, List<AutocompleteUser>> = contacts.groupBy { contact ->
( (
if (contact.source == "users") { if (contact.source == "users") {
@ -432,8 +413,7 @@ fun ContactsItem(
ContactItemRow( ContactItemRow(
contact = contact, contact = contact,
contactsViewModel = contactsViewModel, contactsViewModel = contactsViewModel,
context = context, context = context
selectedContacts = selectedParticipants
) )
Log.d(CompanionClass.TAG, "Contacts:$contact") Log.d(CompanionClass.TAG, "Contacts:$contact")
} }

View File

@ -13,6 +13,7 @@ import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
@ -31,7 +32,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 = MutableStateFlow<List<AutocompleteUser>>(emptyList()) private val selectedParticipants = MutableStateFlow<List<AutocompleteUser>>(emptyList())
val selectedParticipantsList: StateFlow<List<AutocompleteUser>> = selectedParticipants val selectedParticipantsList: StateFlow<List<AutocompleteUser>> = selectedParticipants.asStateFlow()
private val _isAddParticipantsView = MutableStateFlow(false) private val _isAddParticipantsView = MutableStateFlow(false)
val isAddParticipantsView: StateFlow<Boolean> = _isAddParticipantsView val isAddParticipantsView: StateFlow<Boolean> = _isAddParticipantsView
@ -43,6 +44,16 @@ class ContactsViewModel @Inject constructor(
_searchQuery.value = query _searchQuery.value = query
} }
fun selectContact(contact: AutocompleteUser) {
val updatedParticipants = selectedParticipants.value + contact
selectedParticipants.value = updatedParticipants
}
fun deselectContact(contact: AutocompleteUser) {
val updatedParticipants = selectedParticipants.value - contact
selectedParticipants.value = updatedParticipants
}
fun updateSelectedParticipants(participants: List<AutocompleteUser>) { fun updateSelectedParticipants(participants: List<AutocompleteUser>) {
selectedParticipants.value = participants selectedParticipants.value = participants
} }

View File

@ -7,6 +7,7 @@
package com.nextcloud.talk.contacts package com.nextcloud.talk.contacts
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
@ -19,9 +20,9 @@ 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.colorResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
@ -31,12 +32,12 @@ 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
.fillMaxWidth() .fillMaxWidth()
.height(60.dp), .height(60.dp)
.background(color = colorResource(id = R.color.appbar)),
value = text, value = text,
onValueChange = { onTextChange(it) }, onValueChange = { onTextChange(it) },
placeholder = { placeholder = {

View File

@ -388,6 +388,8 @@ HdZk2xusuOEx27cIovRPHwvLcgY+4u3j
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub 928B20E9AD5298CC pub 928B20E9AD5298CC
uid Jakarta Contexts and Dependency Injection <cdi-dev@eclipse.org>
sub 0AA3E5C3D232E79B sub 0AA3E5C3D232E79B
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG v@RELEASE_NAME@ Version: BCPG v@RELEASE_NAME@
@ -403,42 +405,44 @@ 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
=Y1uz 3FJGzPjQA8RuswK/tMxVMAnI5igOgDGugSuGdapzbnS+xiGWC3Pos94VYqMrYYD9
s5E5s0wc
=+V3C
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub 928FBF39003C0425 pub 928FBF39003C0425
@ -1327,6 +1331,8 @@ IprKXtD8103BdNqrPJev2azwqWwxFpN83tEPbK4SwWPgk1nSELXZZ5ClcDgqatg+
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub B943F5CB616566CD pub B943F5CB616566CD
uid Marcel Schnelle <marcelschnelle@aol.com>
sub D73B23600E60600B sub D73B23600E60600B
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG v@RELEASE_NAME@ Version: BCPG v@RELEASE_NAME@
@ -1342,30 +1348,31 @@ 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
=bif8 vCeonVI7Q1CkIHt8u7eMgzfEkaiPLZlI0l0RpfT4pnNieqg=
=mH9D
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub BCF4173966770193 pub BCF4173966770193
@ -4079,6 +4086,43 @@ RT2Fl7A=
=E6L7 =E6L7
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub 31D2D79DF7E85DD3
uid Markus KARG <markus@headcrashing.eu>
sub D091C8FFA534EDA2
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG v@RELEASE_NAME@
mQGNBGTNOPIBDACjeIqMmK4jo8NBVVacAwmqnL6H2/ixU/rPg1WEJSJRQbWu0otK
Zrs+0tOVuYsQReW5tYUwI8hclSkdO95NC8bM7rlxcO6JSixsjzf2cOXajOAvuLMj
OlGtMPblTI88/2nPmj+k3jLClsuqdXNIPdf6DQGIrJjsNfpnCO184ialqIVv0X4y
Z3e8aR/coToU+CcgbWXEyqqZL35RGLs/DR1o0supIm6tBEaDGGxRcrOGTkKaQEXV
v7cZrrXQBSU1kOLko2Lz95ipUn2s7BxM66joOSzmeS6QDRqoL6B+PYMEOGqOP9AI
ZgFdMh5T4WJdzuDGOBrX1FAD1ZLeumz5+Td7Tw/7odKH10ToFf8DIvP0CJnAC8EK
4HGl3NYyKv0gafEmprVNSIDrGLjY7D6bvlJ0vJ70gsQAhJF/tGfa7+pBA3/zuLe7
WD2pSyiqdsyl2mZZ/KRtMXDrhvzSk3H0nxZ4+BQhNLVBW62ty/+XYWn6QOw6tD2v
4vZCXePrel4RhjEAEQEAAbQkTWFya3VzIEtBUkcgPG1hcmt1c0BoZWFkY3Jhc2hp
bmcuZXU+uQGNBGTNOPIBDAD1VVbxdqn7crMimZKLrwWyNVGGu/YKzrpKyO6h40m3
TCUYslIDECFHQL2LqfzixL9w/nXn5Oqx4rTRnlfjCZJkJUv4OnV1dIW065T+bepL
srbZ5cNnMin2336ClJwnD0fkyjrVSAI59roS04WELHvkKyl3LeaqgbJMYEMoweH3
LrrKXGi3fefdEBevRR80ulpw7o0AhPhjd5NWsp/1P43Xl9poNoWaL+7/7W1jKKIa
7VYEOWbRZ/mngwLbSqLOc0lHCsH2InL8+GpdTUCeUtBrImQItKneaxkk+qn8i91d
zL7/Mp3LI7z5ajaXhSj2Wf6/0rg8ObZV9sBJtkEVp0oq7+mFmgeF6reefyKX7g+r
nA1gkdXgMPOBqExXFsXKNLU3mtRd1KsNgdQYDPn9enncmKzjW4ha7NcaFrSWchXE
73Fq43dMbCOejVy4io6+BBSXXHe8M/3/ZB+4EFohRPW0kODnngxzE3E9usuvRJTR
t4c9hhJZdMuhhPs3ry1Cql0AEQEAAYkBvAQYAQoAJhYhBB2FRp2FWcLh31+SUTHS
15336F3TBQJkzTjyAhsMBQkDwmcAAAoJEDHS15336F3T9kMMAIJHtFRvBMfCh9p0
UM4jf0ahE1LX+fUhF4zf/t+vlUmRsIHJNcteD04SxG1WRDc5xxO0IO9oAnX0AgC9
NOCAZaJ11TlXPsCRk32+x8bfCe2Wf2hOLPOfZGO+vj89m74iJf0Gh/0BySMvgwcn
K6WL/xb61EGQUxetB3jLpZU9FwQZq6LjftvZi7r6Y3ui3ogUwTmvq0HlsKCmY7GM
1JLN6xAChZbDU+Ox2F46wyo4XWLfX7HtTe6ykr+yxDwTxx3mJUCwbBYr78Xy16Rq
COcemMTU0U9OWFA1JghFul0moaW+gV+VtZpWR1nCFn5xJOzD2UWFFWomYWiSvL6O
qEVfV/jQYAREDj9vpxlBcfRpTiUlrdFQf4uOQT1G/nXY1KITmq/hNqUdhpUjCoMC
OvdyVwwfG12cTWeQiDQofGqJSptQmsUvegmfF5byUPDbgjCi4tEpWOncOeehs/Hd
ZgMBzI+v/ingWOyKpKqhpZR/50PHA0o23zw8P1BGeQOlr4kFNA==
=jR+6
-----END PGP PUBLIC KEY BLOCK-----
pub 34918B7D3969D2F5 pub 34918B7D3969D2F5
sub 5CE9BCD2ED28F793 sub 5CE9BCD2ED28F793
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----

View File

@ -2229,6 +2229,11 @@
<sha256 value="247f12757acabd706b069445fd31c83c016cc7fe67b0468c582d043ea7d20de1" origin="Generated by Gradle" reason="Artifact is not signed"/> <sha256 value="247f12757acabd706b069445fd31c83c016cc7fe67b0468c582d043ea7d20de1" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact> </artifact>
</component> </component>
<component group="androidx.transition" name="transition" version="1.2.0-rc01">
<artifact name="transition-1.2.0-rc01.pom">
<sha256 value="a45d79acb7e43ccc3ae3268fe174ba6fced0ef82499adfca2ceb1ae52af97dbe" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.transition" name="transition" version="1.4.1"> <component group="androidx.transition" name="transition" version="1.4.1">
<artifact name="transition-1.4.1.aar"> <artifact name="transition-1.4.1.aar">
<sha256 value="36d28d9ec33a8c64313842bce99c95736da5b27a6b3a513639050de82f075726" origin="Generated by Gradle" reason="Artifact is not signed"/> <sha256 value="36d28d9ec33a8c64313842bce99c95736da5b27a6b3a513639050de82f075726" origin="Generated by Gradle" reason="Artifact is not signed"/>
@ -6320,6 +6325,11 @@
<sha256 value="169dd904a4b0f6520cffe658cc62292bfe9f3c14a989fa92120724cde43a9968" origin="Generated by Gradle"/> <sha256 value="169dd904a4b0f6520cffe658cc62292bfe9f3c14a989fa92120724cde43a9968" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </component>
<component group="org.junit" name="junit-bom" version="5.11.0">
<artifact name="junit-bom-5.11.0.pom">
<sha256 value="e67459d4882424ac6374f40db1c8f4a2e88946b340ba072c80be932a2be4644d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit" name="junit-bom" version="5.9.2"> <component group="org.junit" name="junit-bom" version="5.9.2">
<artifact name="junit-bom-5.9.2.pom"> <artifact name="junit-bom-5.9.2.pom">
<sha256 value="2ed07d65845131f5336a86476c9a4056b59d0b58b9815ab3679bb0f36f35f705" origin="Generated by Gradle"/> <sha256 value="2ed07d65845131f5336a86476c9a4056b59d0b58b9815ab3679bb0f36f35f705" origin="Generated by Gradle"/>