diff --git a/android/app/src/main/java/com/shonar/ui/home/HomeScreen.kt b/android/app/src/main/java/com/shonar/ui/home/HomeScreen.kt index 566f49c..40c0050 100644 --- a/android/app/src/main/java/com/shonar/ui/home/HomeScreen.kt +++ b/android/app/src/main/java/com/shonar/ui/home/HomeScreen.kt @@ -26,7 +26,6 @@ import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Mic import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.Pause -import androidx.compose.material.icons.filled.PhoneAndroid import androidx.compose.material.icons.filled.PlayArrow import androidx.compose.material.icons.filled.Settings import androidx.compose.material3.AlertDialog @@ -190,7 +189,7 @@ fun HomeScreen( ShonarSearchField( value = query, onValueChange = { query = it }, - placeholder = "Search saved recordings…", + placeholder = "Search recordings…", modifier = Modifier.fillMaxWidth(), ) } @@ -200,7 +199,6 @@ fun HomeScreen( onSort = { sort = it }, ) } - item { StorageChip() } if (storageOk == false) { item { val ctx = context @@ -227,6 +225,9 @@ fun HomeScreen( ) } } + // Section break between the controls above and the library: + // list spacing (10dp) + this spacer = a deliberate 20dp pause. + item { Spacer(Modifier.height(10.dp)) } if (recordings.isNotEmpty()) { item { Row( @@ -315,31 +316,32 @@ private fun HeaderBlock(recording: Boolean, onOpenSettings: () -> Unit) { ) { Box( modifier = Modifier - .size(44.dp) + .size(76.dp) .background( - cs.primary.copy(alpha = 0.14f), - RoundedCornerShape(12.dp), + androidx.compose.ui.graphics.Color(0xFF0B1220), + RoundedCornerShape(16.dp), ) - .border(1.dp, cs.primary.copy(alpha = 0.45f), RoundedCornerShape(12.dp)), + .border(1.dp, cs.primary.copy(alpha = 0.45f), RoundedCornerShape(16.dp)), contentAlignment = Alignment.Center, ) { - Icon( - Icons.Filled.Mic, + androidx.compose.foundation.Image( + painter = androidx.compose.ui.res.painterResource( + id = com.shonar.R.drawable.ic_launcher_foreground, + ), contentDescription = null, - tint = cs.primary, - modifier = Modifier.size(22.dp), + modifier = Modifier.size(58.dp), ) } Spacer(Modifier.width(12.dp)) Column(Modifier.weight(1f)) { Text( - "Recordings", + "S.H.O.N.A.R.", style = MaterialTheme.typography.headlineSmall, color = cs.onBackground, ) Text( if (recording) "Recording in progress — stays on this phone" - else "Your saved recordings stay on this phone", + else "Self Hosted Oral Notes and Audio Recording", style = MaterialTheme.typography.bodySmall, color = cs.onSurfaceVariant, ) @@ -522,59 +524,62 @@ private fun RecordingRow( Modifier.fillMaxWidth().padding(12.dp), verticalAlignment = Alignment.CenterVertically, ) { - Box( + // Single primary action: large play/pause. No mic tile here — + // the mic icon lives only on the Record button, where it + // unambiguously means "record". + IconButton( + onClick = onPlay, modifier = Modifier - .size(44.dp) + .size(52.dp) .background( - if (selected) cs.primary.copy(alpha = 0.16f) else cs.surfaceVariant, - RoundedCornerShape(10.dp), + cs.primary.copy(alpha = if (playing) 0.22f else 0.14f), + androidx.compose.foundation.shape.CircleShape, ) .border( 1.dp, - if (selected) cs.primary.copy(alpha = 0.5f) else cs.outline.copy(alpha = 0.4f), - RoundedCornerShape(10.dp), + cs.primary.copy(alpha = 0.55f), + androidx.compose.foundation.shape.CircleShape, ), - contentAlignment = Alignment.Center, ) { Icon( - Icons.Filled.Mic, - contentDescription = null, - tint = if (selected) cs.primary else cs.onSurfaceVariant, - modifier = Modifier.size(22.dp), + if (playing) Icons.Filled.Pause else Icons.Filled.PlayArrow, + contentDescription = if (playing) "Pause ${recording.title}" else "Play ${recording.title}", + tint = cs.primary, + modifier = Modifier.size(24.dp), ) } Spacer(Modifier.width(12.dp)) Column(Modifier.weight(1f)) { Text( recording.title, - style = MaterialTheme.typography.titleSmall, + style = MaterialTheme.typography.titleMedium, color = cs.onSurface, maxLines = 2, ) - Spacer(Modifier.height(2.dp)) + Spacer(Modifier.height(4.dp)) Text( "${formatBytes(recording.sizeBytes)} • ${formatDuration(recording.durationMs)} • ${formatDate(recording.createdAtEpochMs)}", - style = MaterialTheme.typography.bodySmall, + style = MaterialTheme.typography.bodyMedium, color = cs.onSurfaceVariant, - maxLines = 1, + maxLines = 2, ) } + // Secondary action: visually quieter — muted tone inside a + // subtle outline so it reads as "more options", not primary. IconButton( - onClick = onPlay, - modifier = Modifier.size(48.dp), + onClick = { menu = true }, + modifier = Modifier + .size(48.dp) + .border( + 1.dp, + cs.outline.copy(alpha = 0.5f), + androidx.compose.foundation.shape.CircleShape, + ), ) { - Icon( - if (playing) Icons.Filled.Pause else Icons.Filled.PlayArrow, - contentDescription = if (playing) "Pause preview" else "Play preview", - tint = cs.primary, - modifier = Modifier.size(24.dp), - ) - } - IconButton(onClick = { menu = true }, modifier = Modifier.size(48.dp)) { Icon( Icons.Filled.MoreVert, contentDescription = "More actions for ${recording.title}", - tint = cs.onSurfaceVariant, + tint = LocalShonarExtras.current.muted, ) } androidx.compose.material3.DropdownMenu( @@ -683,32 +688,9 @@ private fun StorageAccessCard(onGrant: () -> Unit) { } /** Fixed on-phone storage indicator — no selection, nothing leaves the phone. */ -@Composable -private fun StorageChip() { - val cs = MaterialTheme.colorScheme - Card( - shape = RoundedCornerShape(50), - colors = CardDefaults.cardColors(containerColor = cs.surfaceVariant), - border = androidx.compose.foundation.BorderStroke(1.dp, cs.outline.copy(alpha = 0.6f)), - ) { - Row( - Modifier.padding(horizontal = 14.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Icon( - Icons.Filled.PhoneAndroid, contentDescription = null, - modifier = Modifier.size(18.dp), - tint = cs.onSurfaceVariant, - ) - Spacer(Modifier.size(8.dp)) - Text( - "Stored: on this phone", - style = MaterialTheme.typography.labelLarge, - color = cs.onSurfaceVariant, - ) - } - } -} +/* StorageChip removed per design review (2026-09-18): the "Stored: on this + phone" pill, text, icon, background, and reserved space are gone. The + section spacer above keeps the layout rhythm intentional. */ @Composable private fun EmptyState(text: String) { diff --git a/android/app/src/main/java/com/shonar/ui/theme/Components.kt b/android/app/src/main/java/com/shonar/ui/theme/Components.kt index 18facbd..098d018 100644 --- a/android/app/src/main/java/com/shonar/ui/theme/Components.kt +++ b/android/app/src/main/java/com/shonar/ui/theme/Components.kt @@ -25,6 +25,8 @@ import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp /** @@ -63,7 +65,7 @@ fun ShonarSearchField( focusedTextColor = MaterialTheme.colorScheme.onSurface, unfocusedTextColor = MaterialTheme.colorScheme.onSurface, ), - modifier = modifier, + modifier = modifier.semantics { contentDescription = placeholder }, ) }