feat: update group creation composables and let contact parcelize

This commit is contained in:
0x330a 2023-11-02 17:34:52 +11:00
parent fabe2d44da
commit 6c3ac9bc5d
No known key found for this signature in database
GPG Key ID: 267811D6E6A2698C
5 changed files with 69 additions and 26 deletions

View File

@ -7,15 +7,14 @@ import android.view.ViewGroup
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.rememberCoroutineScope
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
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.navigation.dependency
import com.ramcosta.composedestinations.result.NavResult
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.result.ResultRecipient
import dagger.hilt.android.AndroidEntryPoint
@ -25,6 +24,7 @@ import org.thoughtcrime.securesms.conversation.start.NewConversationDelegate
import org.thoughtcrime.securesms.groups.compose.CreateGroup
import org.thoughtcrime.securesms.groups.compose.CreateGroupNavGraph
import org.thoughtcrime.securesms.groups.compose.SelectContacts
import org.thoughtcrime.securesms.groups.compose.StateUpdate
import org.thoughtcrime.securesms.groups.compose.ViewState
import org.thoughtcrime.securesms.groups.destinations.SelectContactScreenDestination
import org.thoughtcrime.securesms.ui.AppTheme
@ -64,11 +64,19 @@ fun CreateGroupScreen(
getDelegate: () -> NewConversationDelegate
) {
val viewState by viewModel.viewState.observeAsState(ViewState.DEFAULT)
val lifecycleScope = rememberCoroutineScope()
val context = LocalContext.current
resultSelectContact.onNavResult { navResult ->
when (navResult) {
is NavResult.Value -> {
viewModel.updateState(StateUpdate.AddContact(navResult.value))
}
is NavResult.Canceled -> { /* do nothing */ }
}
}
CreateGroup(
viewState,
viewModel::updateState,
onClose = {
getDelegate().onDialogClosePressed()
},
@ -90,11 +98,12 @@ fun SelectContactScreen(
val viewState by viewModel.viewState.observeAsState(ViewState.DEFAULT)
val currentMembers = viewState.members
val contacts by viewModel.contacts.observeAsState(initial = emptyList())
val contacts by viewModel.contacts.observeAsState(initial = emptySet())
SelectContacts(
contacts - currentMembers,
onBack = { resultNavigator.navigateBack() },
onClose = { getDelegate().onDialogClosePressed() }
onClose = { getDelegate().onDialogClosePressed() },
onContactsSelected = {}
)
}

View File

@ -8,6 +8,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
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
import javax.inject.Inject
@ -16,10 +17,30 @@ class CreateGroupViewModel @Inject constructor(
private val storage: Storage,
) : ViewModel() {
private val _viewState = MutableLiveData(ViewState.DEFAULT)
val viewState: LiveData<ViewState> = _viewState
private fun create() {
tryCreateGroup()
}
val contacts = liveData { emit(storage.getAllContacts()) }
private inline fun <reified T> MutableLiveData<T>.update(body: T.() -> T) {
this.postValue(body(this.value!!))
}
private val _viewState = MutableLiveData(ViewState.DEFAULT.copy())
val viewState: LiveData<ViewState> = _viewState
fun updateState(stateUpdate: StateUpdate) {
when (stateUpdate) {
is StateUpdate.AddContact -> _viewState.update { copy(members = members + stateUpdate.value) }
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() }
}
}
val contacts
get() = liveData { emit(storage.getAllContacts()) }
fun tryCreateGroup(): Recipient? {
@ -46,7 +67,10 @@ class CreateGroupViewModel @Inject constructor(
if (members.size <= 1) {
_viewState.postValue(
currentState.copy(isLoading = false, error = R.string.activity_create_closed_group_not_enough_group_members_error)
currentState.copy(
isLoading = false,
error = R.string.activity_create_closed_group_not_enough_group_members_error
)
)
}

View File

@ -32,7 +32,6 @@ 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.thoughtcrime.securesms.groups.compose.ViewState.StateUpdate
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
import org.thoughtcrime.securesms.ui.Divider
import org.thoughtcrime.securesms.ui.EditableAvatar
@ -49,6 +48,7 @@ data class CreateGroupState (
@Composable
fun CreateGroup(
viewState: ViewState,
updateState: (StateUpdate) -> Unit,
onSelectContact: () -> Unit,
onBack: () -> Unit,
onClose: () -> Unit,
@ -80,7 +80,7 @@ fun CreateGroup(
val nameDescription = stringResource(id = R.string.AccessibilityId_closed_group_edit_group_name)
OutlinedTextField(
value = viewState.name,
onValueChange = { viewState.updateState(StateUpdate.Name(it)) },
onValueChange = { updateState(StateUpdate.Name(it)) },
modifier = Modifier
.fillMaxWidth()
.align(Alignment.CenterHorizontally)
@ -93,7 +93,7 @@ fun CreateGroup(
val descriptionDescription = stringResource(id = R.string.AccessibilityId_closed_group_edit_group_description)
OutlinedTextField(
value = viewState.description,
onValueChange = { viewState.updateState(StateUpdate.Description(it)) },
onValueChange = { updateState(StateUpdate.Description(it)) },
modifier = Modifier
.fillMaxWidth()
.align(Alignment.CenterHorizontally)
@ -150,13 +150,13 @@ fun CreateGroup(
}
// Group list
memberList(contacts = viewState.members, modifier = Modifier.padding(vertical = 8.dp, horizontal = 24.dp)) { deletedContact ->
viewState.updateState(StateUpdate.RemoveContact(deletedContact))
updateState(StateUpdate.RemoveContact(deletedContact))
}
}
// Create button
val createDescription = stringResource(id = R.string.AccessibilityId_create_closed_group_create_button)
OutlinedButton(
onClick = { viewState.create() },
onClick = { updateState(StateUpdate.Create) },
enabled = viewState.canCreate,
modifier = Modifier
.align(Alignment.CenterHorizontally)
@ -203,6 +203,7 @@ fun ClosedGroupPreview(
viewState = ViewState.DEFAULT.copy(
// override any preview parameters
),
updateState = {},
onSelectContact = {},
onBack = {},
onClose = {},
@ -216,22 +217,21 @@ data class ViewState(
val name: String = "",
val description: String = "",
val members: List<Contact> = emptyList(),
val updateState: (StateUpdate)->Unit,
val create: ()->Unit,
) {
val canCreate
get() = name.isNotEmpty() && members.isNotEmpty()
companion object {
val DEFAULT = ViewState(false, null, updateState = {}, create = {})
val DEFAULT = ViewState(false, null)
}
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 AddContact(val value: Contact): StateUpdate()
}
}
sealed class StateUpdate {
data object Create: StateUpdate()
data class Name(val value: String): StateUpdate()
data class Description(val value: String): StateUpdate()
data class RemoveContact(val value: Contact): StateUpdate()
data class AddContact(val value: Contact): StateUpdate()
}

View File

@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.groups.compose
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -16,21 +17,23 @@ import org.thoughtcrime.securesms.ui.SearchBar
@Composable
fun SelectContacts(
contactListState: List<Contact>,
contactListState: Set<Contact>,
onBack: ()->Unit,
onClose: ()->Unit,
onContactsSelected: (List<Contact>) -> Unit,
) {
var queryFilter by remember { mutableStateOf("") }
// May introduce more advanced filters
val filtered = if (queryFilter.isEmpty()) contactListState
val filtered = if (queryFilter.isEmpty()) contactListState.toList()
else {
contactListState
.filter { contact ->
contact.getSearchName()
.contains(queryFilter)
}
.toList()
}
Column {
@ -45,6 +48,10 @@ fun SelectContacts(
// Search Bar
SearchBar(queryFilter, onValueChanged = { value -> queryFilter = value })
}
items(filtered) { contact ->
}
}
}

View File

@ -32,6 +32,9 @@ class Contact(
*/
var nickname: String? = null,
): Parcelable {
constructor(id: String): this(sessionID = id)
/**
* The name to display in the UI. For local use only.
*/