diff --git a/packages/SystemUI/src/com/android/systemui/axdynamicbar/ui/compose/AxDynamicBarKeyguardChip.kt b/packages/SystemUI/src/com/android/systemui/axdynamicbar/ui/compose/AxDynamicBarKeyguardChip.kt index c85e2624d5f92..a5fc482174b31 100644 --- a/packages/SystemUI/src/com/android/systemui/axdynamicbar/ui/compose/AxDynamicBarKeyguardChip.kt +++ b/packages/SystemUI/src/com/android/systemui/axdynamicbar/ui/compose/AxDynamicBarKeyguardChip.kt @@ -103,6 +103,14 @@ private val ActionIconSize = SizeBadge private val BatteryIconSize = ChipHeight - SpaceXxl private val CountBadgeHeight = ChipHeight / 2 +private val MediaChipHeight = 60.dp +private val MediaChipMaxWidth = 224.dp +private val MediaArtSize = 46.dp +private val MediaActionSize = 30.dp +private val MediaActionIconSize = 16.dp +private val MediaPlayPauseSize = 34.dp +private val MediaPlayPauseIconSize = 18.dp + @Composable private fun rememberChargingParts(batteryString: String): List { return remember(batteryString) { @@ -317,13 +325,18 @@ private fun KeyguardChipBody( val parts = rememberChargingParts(batteryString) val isMultiLineCharging = event is IslandEvent.Charging && parts.size >= 2 - val dynamicHeight = if (isMultiLineCharging) 48.dp else ChipHeight + val dynamicHeight = when { + isMultiLineCharging -> 48.dp + event is IslandEvent.Media -> MediaChipHeight + else -> ChipHeight + } + val dynamicMaxWidth = if (event is IslandEvent.Media) MediaChipMaxWidth else 280.dp Box(contentAlignment = Alignment.Center) { Row( modifier = Modifier .height(dynamicHeight) - .widthIn(min = 48.dp, max = 260.dp) + .widthIn(min = 48.dp, max = dynamicMaxWidth) .clip(ChipShape) .background(accent) .animateContentSize(motionScheme.defaultSpatialSpec()) @@ -373,98 +386,111 @@ private fun KeyguardChipBody( val art = media.albumArt if (art != null) { Image( - bitmap = art.toScaledBitmap(ChipIconSize), + bitmap = art.toScaledBitmap(MediaArtSize), contentDescription = null, modifier = Modifier - .size(ChipIconSize) - .clip(ShapeXs), + .size(MediaArtSize) + .clip(CircleShape), contentScale = ContentScale.Crop, ) } else { - PillEventIcon(media, tint = contentColor, animated = false) + Box( + modifier = Modifier.size(MediaArtSize).clip(CircleShape), + contentAlignment = Alignment.Center, + ) { + PillEventIcon(media, tint = contentColor, animated = false) + } } } - Spacer(Modifier.width(SpaceXs)) - AnimatedContent( - targetState = event, - transitionSpec = { - (fadeIn(motionScheme.defaultEffectsSpec()) + - scaleIn(initialScale = 0.85f, animationSpec = motionScheme.defaultSpatialSpec())) togetherWith - (fadeOut(motionScheme.fastEffectsSpec()) + - scaleOut(targetScale = 0.85f, animationSpec = motionScheme.fastSpatialSpec())) using - SizeTransform(clip = false, sizeAnimationSpec = { _, _ -> motionScheme.defaultSpatialSpec() }) - }, - contentKey = { "${it.track}|${it.artist}" }, - label = "kg_media_text", + Spacer(Modifier.width(SpaceSm)) + Column( modifier = Modifier.weight(1f, fill = false), - ) { ev -> - if (ev.artist.isNotBlank()) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - ev.track.ifEmpty { stringResource(R.string.ax_dynamic_bar_music) }, - style = PillPrimary, - color = contentColor, - maxLines = 1, - softWrap = false, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.widthIn(max = 90.dp).basicMarquee(iterations = 1), - ) - Text( - " · ", - style = MaterialTheme.typography.labelSmall, - color = contentColor.copy(alpha = AlphaHint), - ) - Text( - ev.artist, - style = MaterialTheme.typography.labelSmall, - color = contentColor.copy(alpha = AlphaSecondary), - maxLines = 1, - softWrap = false, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.widthIn(max = 60.dp), - ) + verticalArrangement = Arrangement.Center, + ) { + AnimatedContent( + targetState = event, + transitionSpec = { + (fadeIn(motionScheme.defaultEffectsSpec()) + + scaleIn(initialScale = 0.85f, animationSpec = motionScheme.defaultSpatialSpec())) togetherWith + (fadeOut(motionScheme.fastEffectsSpec()) + + scaleOut(targetScale = 0.85f, animationSpec = motionScheme.fastSpatialSpec())) using + SizeTransform(clip = false, sizeAnimationSpec = { _, _ -> motionScheme.defaultSpatialSpec() }) + }, + contentKey = { "${it.track}|${it.artist}" }, + label = "kg_media_text", + ) { ev -> + if (ev.artist.isNotBlank()) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text( + ev.track.ifEmpty { stringResource(R.string.ax_dynamic_bar_music) }, + style = PillPrimary, + color = contentColor, + maxLines = 1, + softWrap = false, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.widthIn(max = 100.dp).basicMarquee(iterations = 1), + ) + Text( + " · ", + style = MaterialTheme.typography.labelSmall, + color = contentColor.copy(alpha = AlphaHint), + ) + Text( + ev.artist, + style = MaterialTheme.typography.labelSmall, + color = contentColor.copy(alpha = AlphaSecondary), + maxLines = 1, + softWrap = false, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.widthIn(max = 70.dp), + ) + } + } else { + MarqueeText(ev.track.ifEmpty { stringResource(R.string.ax_dynamic_bar_music) }, contentColor, Modifier) } - } else { - MarqueeText(ev.track.ifEmpty { stringResource(R.string.ax_dynamic_bar_music) }, contentColor, Modifier) } - } - Spacer(Modifier.width(SpaceXs)) - ActionButton( - icon = ActionIcon.SKIP_PREV, - color = contentColor, - bgColor = lerp(accent, contentColor, AlphaSubtle), - onClick = { viewModel.skipPrev() }, - size = ActionSize, - iconSize = ActionIconSize, - ) - Spacer(Modifier.width(SpaceXxs)) - Surface( - onClick = { viewModel.togglePlayPause() }, - modifier = Modifier.size(ActionSize), - shape = CircleShape, - color = lerp(accent, contentColor, AlphaSubtle), - ) { - Box(contentAlignment = Alignment.Center, modifier = Modifier.size(ActionSize)) { - Icon( - if (event.isPlaying) Icons.Filled.Pause else Icons.Filled.PlayArrow, - contentDescription = stringResource( - if (event.isPlaying) R.string.ax_dynamic_bar_pause - else R.string.ax_dynamic_bar_play, - ), - tint = contentColor, - modifier = Modifier.size(ActionIconSize), + Spacer(Modifier.height(SpaceXs)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(SpaceLg, Alignment.CenterHorizontally), + verticalAlignment = Alignment.CenterVertically, + ) { + ActionButton( + icon = ActionIcon.SKIP_PREV, + color = contentColor, + bgColor = lerp(accent, contentColor, AlphaSubtle), + onClick = { viewModel.skipPrev() }, + size = MediaActionSize, + iconSize = MediaActionIconSize, + ) + Surface( + onClick = { viewModel.togglePlayPause() }, + modifier = Modifier.size(MediaPlayPauseSize), + shape = CircleShape, + color = lerp(accent, contentColor, AlphaSubtle), + ) { + Box(contentAlignment = Alignment.Center, modifier = Modifier.size(MediaPlayPauseSize)) { + Icon( + if (event.isPlaying) Icons.Filled.Pause else Icons.Filled.PlayArrow, + contentDescription = stringResource( + if (event.isPlaying) R.string.ax_dynamic_bar_pause + else R.string.ax_dynamic_bar_play, + ), + tint = contentColor, + modifier = Modifier.size(MediaPlayPauseIconSize), + ) + } + } + ActionButton( + icon = ActionIcon.SKIP_NEXT, + color = contentColor, + bgColor = lerp(accent, contentColor, AlphaSubtle), + onClick = { viewModel.skipNext() }, + size = MediaActionSize, + iconSize = MediaActionIconSize, ) } } - Spacer(Modifier.width(SpaceXxs)) - ActionButton( - icon = ActionIcon.SKIP_NEXT, - color = contentColor, - bgColor = lerp(accent, contentColor, AlphaSubtle), - onClick = { viewModel.skipNext() }, - size = ActionSize, - iconSize = ActionIconSize, - ) } else if (event is IslandEvent.Sports && event.team2Name.isNotEmpty()) { SportsChipTeamBadge(event.team1Name, event.team1Icon, contentColor) Spacer(Modifier.width(SpaceXs))