From dd6c39f7eb39de8efecd6e9c9c0f53f4291334e5 Mon Sep 17 00:00:00 2001 From: Jeffrey Starke Date: Mon, 21 Apr 2025 11:20:13 -0400 Subject: [PATCH] Update TransferProgressIndicator to support indeterminate progress. Showing exact progress for sticker pack downloads is more complicated than necessary. This PR updates `TransferProgressIndicator` to support displaying indeterminate progress. #### Changeset - Display indeterminate progress when installing a sticker pack. - Remove cancel button from `AvailableStickerPackRow`. - Decrease progress indicator size to match updated design. --- .../TransferProgressIndicator.kt | 109 +++++++++++------- .../stickers/StickerManagementActivityV2.kt | 2 +- .../stickers/StickerManagementViewModelV2.kt | 2 +- .../stickers/StickerPackListItems.kt | 15 +-- app/src/main/res/values/strings.xml | 4 - 5 files changed, 76 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/transfercontrols/TransferProgressIndicator.kt b/app/src/main/java/org/thoughtcrime/securesms/components/transfercontrols/TransferProgressIndicator.kt index 6b47f099b4..21fd9e7f95 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/transfercontrols/TransferProgressIndicator.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/transfercontrols/TransferProgressIndicator.kt @@ -14,13 +14,11 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.StrokeCap -import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.res.painterResource +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.unit.dp import org.signal.core.ui.compose.clickableContainer -import org.thoughtcrime.securesms.R /** * A button that can be used to start, cancel, show progress, and show completion of a data transfer. @@ -51,7 +49,7 @@ private fun StartTransferButton( ) ) { Icon( - painter = state.iconPainter, + imageVector = state.icon, tint = MaterialTheme.colorScheme.onSurface, contentDescription = null, modifier = Modifier @@ -68,34 +66,61 @@ private fun ProgressIndicator( ) { Box( modifier = modifier - .clickableContainer( - contentDescription = null, - onClickLabel = state.cancelButtonOnClickLabel, - onClick = state.onCancelClick - ) - .padding(8.dp) - ) { - Icon( - painter = painterResource(R.drawable.symbol_stop_24), - tint = MaterialTheme.colorScheme.onSurface, - contentDescription = null, - modifier = Modifier - .matchParentSize() - .padding(6.dp) - ) - - CircularProgressIndicator( - progress = { state.progress }, - strokeWidth = 2.dp, - strokeCap = StrokeCap.Round, - trackColor = MaterialTheme.colorScheme.surfaceContainerHighest, - color = MaterialTheme.colorScheme.onSurface, - modifier = Modifier - .matchParentSize() - .clearAndSetSemantics { - contentDescription = state.cancelButtonContentDesc + .then( + if (state.cancelAction != null) { + Modifier.clickableContainer( + contentDescription = null, + onClickLabel = state.cancelAction.onClickLabel, + onClick = state.cancelAction.onClick + ) + } else { + Modifier } - ) + ) + .padding(10.dp) + ) { + state.icon?.let { icon -> + Icon( + imageVector = icon, + tint = MaterialTheme.colorScheme.onSurface, + contentDescription = null, + modifier = Modifier + .matchParentSize() + .padding(6.dp) + ) + } + + val indicatorModifier = Modifier + .matchParentSize() + .then( + if (state.cancelAction != null) { + Modifier.clearAndSetSemantics { + contentDescription = state.cancelAction.contentDesc + } + } else { + Modifier + } + ) + + val progress = state.progress + if (progress == null) { + CircularProgressIndicator( + strokeWidth = 2.dp, + strokeCap = StrokeCap.Round, + trackColor = MaterialTheme.colorScheme.surfaceContainerHighest, + color = MaterialTheme.colorScheme.onSurface, + modifier = indicatorModifier + ) + } else { + CircularProgressIndicator( + progress = { progress }, + strokeWidth = 2.dp, + strokeCap = StrokeCap.Round, + trackColor = MaterialTheme.colorScheme.surfaceContainerHighest, + color = MaterialTheme.colorScheme.onSurface, + modifier = indicatorModifier + ) + } } } @@ -105,7 +130,7 @@ private fun CompleteIcon( modifier: Modifier = Modifier ) { Icon( - painter = state.iconPainter, + imageVector = state.icon, tint = MaterialTheme.colorScheme.onSurface, contentDescription = state.iconContentDesc, modifier = modifier.padding(12.dp) @@ -114,21 +139,27 @@ private fun CompleteIcon( sealed interface TransferProgressState { data class Ready( - val iconPainter: Painter, + val icon: ImageVector, val startButtonContentDesc: String, val startButtonOnClickLabel: String, val onStartClick: () -> Unit ) : TransferProgressState data class InProgress( - val progress: Float, - val cancelButtonContentDesc: String, - val cancelButtonOnClickLabel: String, - val onCancelClick: () -> Unit = {} - ) : TransferProgressState + val icon: ImageVector? = null, + val progress: Float? = null, + val cancelAction: CancelAction? = null + ) : TransferProgressState { + + data class CancelAction( + val contentDesc: String, + val onClickLabel: String, + val onClick: () -> Unit + ) + } data class Complete( - val iconPainter: Painter, + val icon: ImageVector, val iconContentDesc: String ) : TransferProgressState } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementActivityV2.kt index dd6a67c76c..00e577da72 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementActivityV2.kt @@ -279,7 +279,7 @@ private fun AvailableStickersContentPreview() { title = "Bandit the Cat", author = "Agnes Lee", isBlessed = false, - downloadStatus = DownloadStatus.InProgress(progress = 0.37f) + downloadStatus = DownloadStatus.InProgress ), StickerPreviewDataFactory.availablePack( title = "Day by Day", diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementViewModelV2.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementViewModelV2.kt index 384b3725a2..c8d988e751 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementViewModelV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementViewModelV2.kt @@ -58,7 +58,7 @@ data class AvailableStickerPack( ) { sealed class DownloadStatus { data object NotDownloaded : DownloadStatus() - data class InProgress(val progress: Float) : DownloadStatus() + data object InProgress : DownloadStatus() data object Downloaded : DownloadStatus() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackListItems.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackListItems.kt index b46e27ccf3..ff63b4d942 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackListItems.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackListItems.kt @@ -20,7 +20,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.dp @@ -54,7 +53,6 @@ fun StickerPackSectionHeader( fun AvailableStickerPackRow( pack: AvailableStickerPack, onStartDownloadClick: () -> Unit = {}, - onCancelDownloadClick: () -> Unit = {}, modifier: Modifier = Modifier ) { Row( @@ -74,21 +72,16 @@ fun AvailableStickerPackRow( TransferProgressIndicator( state = when (pack.downloadStatus) { DownloadStatus.NotDownloaded -> TransferProgressState.Ready( - iconPainter = painterResource(id = R.drawable.symbol_arrow_circle_down_24), + icon = ImageVector.vectorResource(id = R.drawable.symbol_arrow_circle_down_24), startButtonContentDesc = stringResource(R.string.StickerManagement_accessibility_download), startButtonOnClickLabel = stringResource(R.string.StickerManagement_accessibility_download_pack, pack.record.title), onStartClick = onStartDownloadClick ) - is DownloadStatus.InProgress -> TransferProgressState.InProgress( - progress = pack.downloadStatus.progress, - cancelButtonContentDesc = stringResource(R.string.StickerManagement_accessibility_cancel), - cancelButtonOnClickLabel = stringResource(R.string.StickerManagement_accessibility_cancel_downloading_pack, pack.record.title), - onCancelClick = onCancelDownloadClick - ) + is DownloadStatus.InProgress -> TransferProgressState.InProgress() DownloadStatus.Downloaded -> TransferProgressState.Complete( - iconPainter = painterResource(id = R.drawable.symbol_check_24), + icon = ImageVector.vectorResource(id = R.drawable.symbol_check_24), iconContentDesc = stringResource(R.string.StickerManagement_accessibility_downloaded_checkmark, pack.record.title) ) } @@ -227,7 +220,7 @@ private fun AvailableStickerPackRowPreviewDownloading() = SignalTheme { title = "Bandit the Cat", author = "Agnes Lee", isBlessed = false, - downloadStatus = DownloadStatus.InProgress(progress = 0.37f) + downloadStatus = DownloadStatus.InProgress ) ) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3736cefcdb..4fa0ff50e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2808,16 +2808,12 @@ Signal artist series Download %s sticker pack - - Cancel downloading %s sticker pack Downloaded checkmark Drag and drop handle Download - - Cancel No stickers installed