feat: need to fix a persist for group members but group with selected contacts working now
This commit is contained in:
parent
c19bd3da3d
commit
5a2fdb0e83
|
@ -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())
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue