feat: need to fix a persist for group members but group with selected contacts working now

This commit is contained in:
0x330a 2023-11-03 17:45:57 +11:00
parent c19bd3da3d
commit 5a2fdb0e83
7 changed files with 120 additions and 41 deletions

View File

@ -241,7 +241,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
private val viewModel: ConversationViewModel by viewModels {
var threadId = intent.getLongExtra(THREAD_ID, -1L)
if (threadId == -1L) {
intent.getParcelableExtra<Address>(ADDRESS)?.let { it ->
intent.getParcelableExtra(ADDRESS, Address::class.java)?.let { it ->
threadId = threadDb.getThreadIdIfExistsFor(it.serialize())
if (threadId == -1L) {
val sessionId = SessionId(it.serialize())

View File

@ -1,14 +1,17 @@
package org.thoughtcrime.securesms.groups
import android.content.Intent
import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
import androidx.fragment.app.Fragment
import androidx.hilt.navigation.compose.hiltViewModel
import com.ramcosta.composedestinations.DestinationsNavHost
@ -23,6 +26,7 @@ import kotlinx.parcelize.Parcelize
import network.loki.messenger.databinding.FragmentCreateGroupBinding
import org.session.libsession.messaging.contacts.Contact
import org.thoughtcrime.securesms.conversation.start.NewConversationDelegate
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
import org.thoughtcrime.securesms.groups.compose.CreateGroup
import org.thoughtcrime.securesms.groups.compose.CreateGroupNavGraph
import org.thoughtcrime.securesms.groups.compose.SelectContacts
@ -59,7 +63,7 @@ class CreateGroupFragment : Fragment() {
}
@Parcelize
data class ContactList(val contacts: List<Contact>) : Parcelable
data class ContactList(val contacts: Set<Contact>) : Parcelable
@CreateGroupNavGraph(start = true)
@Composable
@ -83,6 +87,18 @@ fun CreateGroupScreen(
}
}
val context = LocalContext.current
viewState.createdGroup?.let { group ->
SideEffect {
getDelegate().onDialogClosePressed()
val intent = Intent(context, ConversationActivityV2::class.java).apply {
putExtra(ConversationActivityV2.ADDRESS, group.address)
}
context.startActivity(intent)
}
}
CreateGroup(
viewState,
viewModel::updateState,

View File

@ -4,9 +4,10 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import network.loki.messenger.R
import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.database.Storage
import org.thoughtcrime.securesms.groups.compose.StateUpdate
import org.thoughtcrime.securesms.groups.compose.ViewState
@ -17,10 +18,6 @@ class CreateGroupViewModel @Inject constructor(
private val storage: Storage,
) : ViewModel() {
private fun create() {
tryCreateGroup()
}
private inline fun <reified T> MutableLiveData<T>.update(body: T.() -> T) {
this.postValue(body(this.value!!))
}
@ -35,14 +32,14 @@ class CreateGroupViewModel @Inject constructor(
is StateUpdate.Description -> _viewState.update { copy(description = stateUpdate.value) }
is StateUpdate.Name -> _viewState.update { copy(name = stateUpdate.value) }
is StateUpdate.RemoveContact -> _viewState.update { copy(members = members - stateUpdate.value) }
StateUpdate.Create -> { tryCreateGroup() }
StateUpdate.Create -> { viewModelScope.launch { tryCreateGroup() } }
}
}
val contacts
get() = liveData { emit(storage.getAllContacts()) }
fun tryCreateGroup(): Recipient? {
fun tryCreateGroup() {
val currentState = _viewState.value!!
@ -55,10 +52,9 @@ class CreateGroupViewModel @Inject constructor(
// do some validation
// need a name
if (name.isEmpty()) {
_viewState.postValue(
return _viewState.postValue(
currentState.copy(isLoading = false, error = R.string.error)
)
return null
}
storage.getAllContacts().forEach { contact ->
@ -77,8 +73,14 @@ class CreateGroupViewModel @Inject constructor(
// make a group
val newGroup = storage.createNewGroup(name, description, members)
if (!newGroup.isPresent) {
_viewState.postValue(currentState.copy(isLoading = false, error = null))
// show a generic couldn't create or something?
return _viewState.postValue(currentState.copy(isLoading = false, error = null))
} else {
return _viewState.postValue(currentState.copy(
isLoading = false,
error = null,
createdGroup = newGroup.get())
)
}
return newGroup.orNull()
}
}

View File

@ -14,6 +14,7 @@ import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.RadioButton
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@ -54,10 +55,54 @@ fun EmptyPlaceholder(modifier: Modifier = Modifier) {
}
}
fun LazyListScope.memberList(
fun LazyListScope.multiSelectMemberList(
contacts: List<Contact>,
modifier: Modifier = Modifier,
onDelete: (Contact) -> Unit
selectedContacts: Set<Contact> = emptySet(),
onListUpdated: (Set<Contact>)->Unit = {},
) {
items(contacts) { contact ->
val isSelected = selectedContacts.contains(contact)
val update = {
val newList =
if (isSelected) selectedContacts - contact
else selectedContacts + contact
onListUpdated(newList)
}
Row(modifier = modifier.fillMaxWidth()
.clickable(onClick = update)
.padding(vertical = 8.dp, horizontal = 24.dp),
verticalAlignment = CenterVertically
) {
ContactPhoto(
contact = contact,
modifier = Modifier
.size(48.dp)
)
MemberName(name = contact.getSearchName())
RadioButton(selected = isSelected, onClick = update)
}
}
}
@Composable
fun RowScope.MemberName(
name: String
) = Text(
text = name,
fontWeight = FontWeight.Bold,
modifier = Modifier
.weight(1f)
.padding(16.dp)
.align(CenterVertically)
)
fun LazyListScope.deleteMemberList(
contacts: List<Contact>,
modifier: Modifier = Modifier,
onDelete: (Contact) -> Unit,
) {
item {
Text(
@ -80,23 +125,16 @@ fun LazyListScope.memberList(
.size(48.dp)
.align(CenterVertically)
)
Text(
text = contact.getSearchName(),
fontWeight = FontWeight.Bold,
modifier = Modifier
.weight(1f)
.padding(16.dp)
.align(CenterVertically)
)
MemberName(name = contact.getSearchName())
Image(
painterResource(id = R.drawable.ic_baseline_close_24),
null,
Modifier
modifier = Modifier
.size(32.dp)
.align(CenterVertically)
.clickable {
onDelete(contact)
}
},
)
}
}
@ -141,12 +179,9 @@ fun PreviewMemberList(
)
PreviewTheme(themeResId = themeResId) {
LazyColumn {
memberList(
previewMembers.toList(),
Modifier.padding(vertical = 8.dp, horizontal = 24.dp)
) { deleted ->
}
multiSelectMemberList(
contacts = previewMembers.toList(),
)
}
}
}

View File

@ -32,6 +32,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import network.loki.messenger.R
import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
import org.thoughtcrime.securesms.ui.Divider
import org.thoughtcrime.securesms.ui.EditableAvatar
@ -149,7 +150,7 @@ fun CreateGroup(
}
}
// Group list
memberList(contacts = viewState.members, modifier = Modifier.padding(vertical = 8.dp, horizontal = 24.dp)) { deletedContact ->
deleteMemberList(contacts = viewState.members, modifier = Modifier.padding(vertical = 8.dp, horizontal = 24.dp)) { deletedContact ->
updateState(StateUpdate.RemoveContact(deletedContact))
}
}
@ -218,6 +219,7 @@ data class ViewState(
val name: String = "",
val description: String = "",
val members: List<Contact> = emptyList(),
val createdGroup: Recipient? = null,
) {
val canCreate
@ -234,5 +236,5 @@ sealed class StateUpdate {
data class Name(val value: String): StateUpdate()
data class Description(val value: String): StateUpdate()
data class RemoveContact(val value: Contact): StateUpdate()
data class AddContacts(val value: List<Contact>): StateUpdate()
data class AddContacts(val value: Set<Contact>): StateUpdate()
}

View File

@ -1,26 +1,36 @@
package org.thoughtcrime.securesms.groups.compose
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
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.foundation.shape.CircleShape
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import network.loki.messenger.R
import org.session.libsession.messaging.contacts.Contact
import org.thoughtcrime.securesms.home.search.getSearchName
import org.thoughtcrime.securesms.ui.NavigationBar
import org.thoughtcrime.securesms.ui.SearchBar
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun SelectContacts(
contactListState: Set<Contact>,
onBack: ()->Unit,
onClose: ()->Unit,
onContactsSelected: (List<Contact>) -> Unit,
onContactsSelected: (Set<Contact>) -> Unit,
) {
var queryFilter by remember { mutableStateOf("") }
@ -30,12 +40,16 @@ fun SelectContacts(
else {
contactListState
.filter { contact ->
contact.getSearchName()
contact.getSearchName().lowercase()
.contains(queryFilter)
}
.toList()
}
var selected by remember {
mutableStateOf(emptySet<Contact>())
}
Column {
NavigationBar(
title = stringResource(id = R.string.activity_create_closed_group_select_contacts),
@ -43,14 +57,24 @@ fun SelectContacts(
onClose = onClose
)
LazyColumn {
item {
LazyColumn(modifier = Modifier.weight(1f)) {
stickyHeader {
// Search Bar
SearchBar(queryFilter, onValueChanged = { value -> queryFilter = value })
}
items(filtered) { contact ->
multiSelectMemberList(
contacts = filtered.toList(),
selectedContacts = selected,
onListUpdated = { selected = it },
)
}
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxWidth()) {
OutlinedButton(
onClick = { onContactsSelected(selected) },
shape = CircleShape,
modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp)) {
Text(stringResource(id = R.string.ok))
}
}
}

View File

@ -118,7 +118,7 @@ data class ConfigurationSyncJob(val destination: Destination) : Job {
)
return ConfigMessageInformation(
if (signingKey != null && ed25519PubKey != null) {
if (signingKey != null && ed25519PubKey == null) {
SnodeAPI.buildAuthenticatedStoreBatchInfo(
namespace(),
message,