Added progress indicator for group editing (#875)

* Added progress indicator for group editing

* Max size on AndroidView and remove background, add semantics

* More update

* Reuse LoadingDialog

* Comment
pull/1709/head
SessionHero01 4 months ago committed by GitHub
parent 6b7afb8969
commit 46653d9229
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -264,6 +264,9 @@ class GroupManagerV2Impl @Inject constructor(
subAccountTokens = subAccountTokens
)
// Before we send the invitation, we need to make sure the configs are pushed
configFactory.waitUntilGroupConfigsPushed(group)
// Call the API
try {
val swarmNode = SnodeAPI.getSingleTargetSnode(group.hexString).await()

@ -28,6 +28,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
@ -53,9 +54,10 @@ import org.thoughtcrime.securesms.groups.getLabel
import org.thoughtcrime.securesms.ui.AlertDialog
import org.thoughtcrime.securesms.ui.DialogButtonModel
import org.thoughtcrime.securesms.ui.GetString
import org.thoughtcrime.securesms.ui.components.BackAppBar
import org.thoughtcrime.securesms.ui.LoadingDialog
import org.thoughtcrime.securesms.ui.components.ActionSheet
import org.thoughtcrime.securesms.ui.components.ActionSheetItemData
import org.thoughtcrime.securesms.ui.components.BackAppBar
import org.thoughtcrime.securesms.ui.components.PrimaryOutlineButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedTextField
import org.thoughtcrime.securesms.ui.components.annotatedStringResource
@ -99,6 +101,7 @@ fun EditGroupScreen(
onMemberClicked = viewModel::onMemberClicked,
hideActionSheet = viewModel::hideActionBottomSheet,
clickedMember = viewModel.clickedMember.collectAsState().value,
showLoading = viewModel.inProgress.collectAsState().value,
)
}
@ -119,7 +122,7 @@ fun EditGroupScreen(
@Serializable
private object RouteEditGroup
@OptIn(ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
@Composable
fun EditGroup(
onBack: () -> Unit,
@ -141,6 +144,7 @@ fun EditGroup(
members: List<GroupMemberState>,
showAddMembers: Boolean,
showingError: String?,
showLoading: Boolean,
onErrorDismissed: () -> Unit,
) {
val (showingConfirmRemovingMember, setShowingConfirmRemovingMember) = remember {
@ -157,115 +161,120 @@ fun EditGroup(
)
}
) { paddingValues ->
Column(modifier = Modifier.padding(paddingValues)) {
GroupMinimumVersionBanner()
// Group name title
Crossfade(editingName != null, label = "Editable group name") { showNameEditing ->
if (showNameEditing) {
GroupNameContainer {
IconButton(
modifier = Modifier.size(LocalDimensions.current.spacing),
onClick = onEditNameCancelClicked) {
Icon(
painter = painterResource(R.drawable.ic_x),
contentDescription = stringResource(R.string.AccessibilityId_cancel),
tint = LocalColors.current.text,
)
}
Box {
Column(modifier = Modifier.padding(paddingValues)) {
GroupMinimumVersionBanner()
// Group name title
Crossfade(editingName != null, label = "Editable group name") { showNameEditing ->
if (showNameEditing) {
GroupNameContainer {
IconButton(
modifier = Modifier.size(LocalDimensions.current.spacing),
onClick = onEditNameCancelClicked
) {
Icon(
painter = painterResource(R.drawable.ic_x),
contentDescription = stringResource(R.string.AccessibilityId_cancel),
tint = LocalColors.current.text,
)
}
SessionOutlinedTextField(
modifier = Modifier.widthIn(
min = LocalDimensions.current.mediumSpacing,
max = maxNameWidth
)
.qaTag(stringResource(R.string.AccessibilityId_groupName)),
text = editingName.orEmpty(),
onChange = onEditingNameValueChanged,
textStyle = LocalType.current.h8,
singleLine = true,
innerPadding = PaddingValues(
horizontal = LocalDimensions.current.spacing,
vertical = LocalDimensions.current.smallSpacing
SessionOutlinedTextField(
modifier = Modifier
.widthIn(
min = LocalDimensions.current.mediumSpacing,
max = maxNameWidth
)
.qaTag(stringResource(R.string.AccessibilityId_groupName)),
text = editingName.orEmpty(),
onChange = onEditingNameValueChanged,
textStyle = LocalType.current.h8,
singleLine = true,
innerPadding = PaddingValues(
horizontal = LocalDimensions.current.spacing,
vertical = LocalDimensions.current.smallSpacing
)
)
)
IconButton(
modifier = Modifier.size(LocalDimensions.current.spacing),
onClick = onEditNameConfirmed) {
Icon(
painter = painterResource(R.drawable.check),
contentDescription = stringResource(R.string.AccessibilityId_confirm),
tint = LocalColors.current.text,
)
IconButton(
modifier = Modifier.size(LocalDimensions.current.spacing),
onClick = onEditNameConfirmed
) {
Icon(
painter = painterResource(R.drawable.check),
contentDescription = stringResource(R.string.AccessibilityId_confirm),
tint = LocalColors.current.text,
)
}
}
}
} else {
GroupNameContainer {
Spacer(modifier = Modifier.weight(1f))
Text(
text = groupName,
style = LocalType.current.h4,
textAlign = TextAlign.Center,
modifier = Modifier.widthIn(max = maxNameWidth)
.padding(vertical = LocalDimensions.current.smallSpacing),
)
} else {
GroupNameContainer {
Spacer(modifier = Modifier.weight(1f))
Text(
text = groupName,
style = LocalType.current.h4,
textAlign = TextAlign.Center,
modifier = Modifier
.widthIn(max = maxNameWidth)
.padding(vertical = LocalDimensions.current.smallSpacing),
)
Box(modifier = Modifier.weight(1f)) {
if (canEditName) {
IconButton(
modifier = Modifier.qaTag(stringResource(R.string.AccessibilityId_groupName)),
onClick = onEditNameClicked
) {
Icon(
painterResource(R.drawable.ic_baseline_edit_24),
contentDescription = stringResource(R.string.edit),
tint = LocalColors.current.text,
)
Box(modifier = Modifier.weight(1f)) {
if (canEditName) {
IconButton(
modifier = Modifier.qaTag(stringResource(R.string.AccessibilityId_groupName)),
onClick = onEditNameClicked
) {
Icon(
painterResource(R.drawable.ic_baseline_edit_24),
contentDescription = stringResource(R.string.edit),
tint = LocalColors.current.text,
)
}
}
}
}
}
}
}
// Header & Add member button
Row(
modifier = Modifier.padding(
horizontal = LocalDimensions.current.smallSpacing,
vertical = LocalDimensions.current.xxsSpacing
),
verticalAlignment = CenterVertically
) {
Text(
stringResource(R.string.groupMembers),
modifier = Modifier.weight(1f),
style = LocalType.current.large,
color = LocalColors.current.text
)
if (showAddMembers) {
PrimaryOutlineButton(
stringResource(R.string.membersInvite),
onClick = onAddMemberClick,
modifier = Modifier.qaTag(stringResource(R.string.AccessibilityId_membersInvite))
// Header & Add member button
Row(
modifier = Modifier.padding(
horizontal = LocalDimensions.current.smallSpacing,
vertical = LocalDimensions.current.xxsSpacing
),
verticalAlignment = CenterVertically
) {
Text(
stringResource(R.string.groupMembers),
modifier = Modifier.weight(1f),
style = LocalType.current.large,
color = LocalColors.current.text
)
if (showAddMembers) {
PrimaryOutlineButton(
stringResource(R.string.membersInvite),
onClick = onAddMemberClick,
modifier = Modifier.qaTag(stringResource(R.string.AccessibilityId_membersInvite))
)
}
}
}
// List of members
LazyColumn(modifier = Modifier) {
items(members) { member ->
// Each member's view
EditMemberItem(
modifier = Modifier.fillMaxWidth(),
member = member,
onClick = { onMemberClicked(member) }
)
// List of members
LazyColumn(modifier = Modifier) {
items(members) { member ->
// Each member's view
EditMemberItem(
modifier = Modifier.fillMaxWidth(),
member = member,
onClick = { onMemberClicked(member) }
)
}
}
}
}
@ -305,6 +314,10 @@ fun EditGroup(
)
}
if (showLoading) {
LoadingDialog()
}
val context = LocalContext.current
LaunchedEffect(showingError) {
@ -515,7 +528,8 @@ private fun EditGroupPreview3() {
onErrorDismissed = {},
onMemberClicked = {},
hideActionSheet = {},
clickedMember = null
clickedMember = null,
showLoading = true,
)
}
}
@ -589,7 +603,8 @@ private fun EditGroupPreview() {
onErrorDismissed = {},
onMemberClicked = {},
hideActionSheet = {},
clickedMember = null
clickedMember = null,
showLoading = false,
)
}
}
@ -655,7 +670,8 @@ private fun EditGroupEditNamePreview() {
onErrorDismissed = {},
onMemberClicked = {},
hideActionSheet = {},
clickedMember = null
clickedMember = null,
showLoading = false,
)
}
}

@ -128,7 +128,8 @@ fun AlertDialog(
text = it,
textAlign = TextAlign.Center,
style = LocalType.current.h7,
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsSpacing)
modifier = Modifier
.padding(bottom = LocalDimensions.current.xxsSpacing)
.qaTag(stringResource(R.string.AccessibilityId_modalTitle))
)
}
@ -281,22 +282,33 @@ fun LoadingDialog(
modifier = modifier,
onDismissRequest = {},
content = {
DialogBg {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(LocalDimensions.current.spacing)
) {
if (title.isNullOrBlank()) {
Box {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.CenterHorizontally)
modifier = Modifier.align(Alignment.Center),
//TODO: Leave this as hardcoded color for now as the dialog background (scrim)
// always seems to be dark. Can can revisit later when we have more control over
// the scrim color.
color = Color.White
)
}
} else {
DialogBg {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(LocalDimensions.current.spacing)
) {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Spacer(modifier = Modifier.height(LocalDimensions.current.spacing))
Spacer(modifier = Modifier.height(LocalDimensions.current.spacing))
title?.let {
Text(
it,
modifier = Modifier.align(Alignment.CenterHorizontally)
title,
modifier = Modifier
.align(Alignment.CenterHorizontally)
.qaTag(stringResource(R.string.AccessibilityId_modalTitle)),
style = LocalType.current.large
)

Loading…
Cancel
Save