From 1a3c473b3da50ac8b3b08b1d16e10c9f47adb462 Mon Sep 17 00:00:00 2001 From: gagip Date: Thu, 26 Mar 2026 02:27:24 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20Compose=20UI=20=ED=92=88=EC=A7=88=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20=E2=80=94=20contentType,=20derivedStateOf,?= =?UTF-8?q?=20=EC=83=89=EC=83=81=20=ED=86=A0=ED=81=B0,=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ZenAllTracksTabContent: isSelectionMode에 derivedStateOf 적용, itemsIndexed에 contentType 추가 - ZenPlayerBar: playbackProgress에 derivedStateOf 적용, Color.White → MaterialTheme 토큰으로 교체 - PlaylistDetailScreen: itemsIndexed contentType 추가, TealThemeColor 하드코딩 → MaterialTheme 토큰으로 교체 - AlbumArtThumbnail: contentDescription null → '앨범 아트'로 접근성 보완 - ZenPomodoroTimer: 타이머 Text에 semantics contentDescription 추가 --- .../core/ui/component/AlbumArtThumbnail.kt | 2 +- .../features/playlist/ui/PlaylistDetailScreen.kt | 6 +++--- .../timer/ui/components/ZenPomodoroTimer.kt | 6 +++++- .../zenplayer/zen/miniplayer/ZenPlayerBar.kt | 14 +++++++++----- .../zen/musicselect/ZenAllTracksTabContent.kt | 5 +++-- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/happyseal/zenplayer/core/ui/component/AlbumArtThumbnail.kt b/app/src/main/java/com/happyseal/zenplayer/core/ui/component/AlbumArtThumbnail.kt index fcc11241..6f1f0790 100644 --- a/app/src/main/java/com/happyseal/zenplayer/core/ui/component/AlbumArtThumbnail.kt +++ b/app/src/main/java/com/happyseal/zenplayer/core/ui/component/AlbumArtThumbnail.kt @@ -67,7 +67,7 @@ fun AlbumArtThumbnail( ) { Icon( imageVector = Icons.Filled.MusicNote, - contentDescription = null, + contentDescription = "앨범 아트", tint = color.contentColor(), ) } diff --git a/app/src/main/java/com/happyseal/zenplayer/features/playlist/ui/PlaylistDetailScreen.kt b/app/src/main/java/com/happyseal/zenplayer/features/playlist/ui/PlaylistDetailScreen.kt index 0c2acba0..2b22f9fe 100644 --- a/app/src/main/java/com/happyseal/zenplayer/features/playlist/ui/PlaylistDetailScreen.kt +++ b/app/src/main/java/com/happyseal/zenplayer/features/playlist/ui/PlaylistDetailScreen.kt @@ -144,7 +144,7 @@ fun PlaylistDetailScreen( modifier = Modifier.padding(bottom = ZenDimension.Spacing.S), ) } - itemsIndexed(state.tracks, key = { _, playlistTrack -> playlistTrack.rowId }) { index, playlistTrack -> + itemsIndexed(state.tracks, key = { _, playlistTrack -> playlistTrack.rowId }, contentType = { _, _ -> "playlistTrack" }) { index, playlistTrack -> val isActive = miniPlayerUiState.currentTrackTitle == playlistTrack.track.title PlaylistTrackItem( playlistTrack = playlistTrack, @@ -284,13 +284,13 @@ private fun PlaylistTrackItem( Box( modifier = Modifier .matchParentSize() - .background(TealThemeColor.TealPrimary.copy(alpha = 0.4f)), + .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.4f)), contentAlignment = Alignment.Center, ) { Icon( imageVector = Icons.Default.PlayArrow, contentDescription = null, - tint = TealThemeColor.TealOnPrimary, + tint = MaterialTheme.colorScheme.onPrimary, modifier = Modifier.size(ZenDimension.IconSize.S), ) } diff --git a/app/src/main/java/com/happyseal/zenplayer/features/timer/ui/components/ZenPomodoroTimer.kt b/app/src/main/java/com/happyseal/zenplayer/features/timer/ui/components/ZenPomodoroTimer.kt index d01a783a..fd085e7f 100644 --- a/app/src/main/java/com/happyseal/zenplayer/features/timer/ui/components/ZenPomodoroTimer.kt +++ b/app/src/main/java/com/happyseal/zenplayer/features/timer/ui/components/ZenPomodoroTimer.kt @@ -58,6 +58,8 @@ import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp @@ -311,7 +313,9 @@ private fun TimerCircleContent( text = pomodoroUiState.remaining.toTimeString(), style = TimerTextStyle.copy(fontSize = 48.sp, fontWeight = FontWeight.Light), color = sessionColor, - modifier = Modifier.alpha(blinkAlpha), + modifier = Modifier + .alpha(blinkAlpha) + .semantics { contentDescription = "남은 시간 ${pomodoroUiState.remaining.toTimeString()}" }, ) Spacer(modifier = Modifier.height(8.dp)) diff --git a/app/src/main/java/com/happyseal/zenplayer/zen/miniplayer/ZenPlayerBar.kt b/app/src/main/java/com/happyseal/zenplayer/zen/miniplayer/ZenPlayerBar.kt index 3a63f6ee..bba63dde 100644 --- a/app/src/main/java/com/happyseal/zenplayer/zen/miniplayer/ZenPlayerBar.kt +++ b/app/src/main/java/com/happyseal/zenplayer/zen/miniplayer/ZenPlayerBar.kt @@ -45,6 +45,7 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf @@ -95,7 +96,7 @@ internal fun ZenPlayerBar( Surface( modifier = modifier.fillMaxWidth(), - color = Color.White.copy(alpha = 0.8f), + color = MaterialTheme.colorScheme.surface.copy(alpha = 0.8f), shape = RoundedCornerShape(topStart = ZenDimension.Corner.Pill, topEnd = ZenDimension.Corner.Pill), border = BorderStroke(1.dp, Color.White.copy(alpha = ZenAlpha.DISABLED)), ) { @@ -230,8 +231,11 @@ private fun MusicContent( Spacer(modifier = Modifier.height(ZenDimension.Spacing.S)) - val playbackProgress = - if (duration > 0) (currentPosition.toFloat() / duration).coerceIn(0f, 1f) else 0f + val playbackProgress by remember(duration, currentPosition) { + derivedStateOf { + if (duration > 0) (currentPosition.toFloat() / duration).coerceIn(0f, 1f) else 0f + } + } var sliderPosition by remember { mutableFloatStateOf(playbackProgress) } var isDragging by remember { mutableStateOf(false) } LaunchedEffect(playbackProgress) { @@ -417,14 +421,14 @@ private fun PlayPauseButton( imageVector = Icons.Default.Pause, contentDescription = stringResource(R.string.cd_pause), modifier = Modifier.size(ZenDimension.IconSize.L), - tint = Color.White, + tint = MaterialTheme.colorScheme.onPrimary, ) } else { Icon( imageVector = Icons.Default.PlayArrow, contentDescription = stringResource(R.string.cd_play), modifier = Modifier.size(ZenDimension.IconSize.L), - tint = Color.White, + tint = MaterialTheme.colorScheme.onPrimary, ) } } diff --git a/app/src/main/java/com/happyseal/zenplayer/zen/musicselect/ZenAllTracksTabContent.kt b/app/src/main/java/com/happyseal/zenplayer/zen/musicselect/ZenAllTracksTabContent.kt index 51def4e1..6f600e1a 100644 --- a/app/src/main/java/com/happyseal/zenplayer/zen/musicselect/ZenAllTracksTabContent.kt +++ b/app/src/main/java/com/happyseal/zenplayer/zen/musicselect/ZenAllTracksTabContent.kt @@ -43,6 +43,7 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -78,7 +79,7 @@ internal fun AllTracksTabContent( ) { val context = LocalContext.current var selectedTracks by remember { mutableStateOf(setOf()) } - val isSelectionMode = selectedTracks.isNotEmpty() + val isSelectionMode by remember { derivedStateOf { selectedTracks.isNotEmpty() } } var showPlaylistDialog by remember { mutableStateOf(false) } Box(modifier = modifier.fillMaxSize()) { @@ -252,7 +253,7 @@ private fun TrackListContent( ), verticalArrangement = Arrangement.spacedBy(ZenDimension.Spacing.M), ) { - itemsIndexed(uiState.tracks, key = { _, track -> track.id }) { index, track -> + itemsIndexed(uiState.tracks, key = { _, track -> track.id }, contentType = { _, _ -> "track" }) { index, track -> val isSelected = track in selectedTracks TrackItem( track = track,