From c6a513069c96d290353ab1e907ada2407c81058c Mon Sep 17 00:00:00 2001 From: dadachi Date: Tue, 28 Apr 2026 08:08:20 +0900 Subject: [PATCH 1/2] ShopDetailCardView: 2-column layout with description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirror iOS ItemTagListCardView's 2-column HStack pattern in ShopDetailCardView so each item-tag row in ShopDetailView surfaces the description alongside the name. Layout: - Left column (weight 1): name (titleLarge), description (bodySmall, max 2 lines, ellipsis) hidden when blank. - Right column (minWidth 82dp, end-aligned): state tag — CompletedTag + completedAt for Completed; IdlingTag for Idled. Matches iOS ItemTagListCardView's HStack { VStack(alignment: .leading) [name, description] | Spacer | VStack(alignment: .trailing) [tag, completedAt] } shape. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../ui/shop_detail/ShopDetailCardView.kt | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailCardView.kt b/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailCardView.kt index 1451666..57cb2aa 100644 --- a/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailCardView.kt +++ b/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailCardView.kt @@ -5,12 +5,13 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.nativeapptemplate.nativeapptemplatefree.model.Data import com.nativeapptemplate.nativeapptemplatefree.model.ItemTagState @@ -22,45 +23,54 @@ import com.nativeapptemplate.nativeapptemplatefree.utils.DateUtility.cardDateTim fun ShopDetailCardView( data: Data, ) { + val description = data.getDescription() + val state = data.getItemTagState() + val completedAt = data.getCompletedAt() + Row( horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(16.dp), ) { - val nameFontSize = with(LocalDensity.current) { MaterialTheme.typography.titleLarge.fontSize.value.dp.toSp() } - val timestampFontSize = with(LocalDensity.current) { MaterialTheme.typography.bodySmall.fontSize.value.dp.toSp() } - val completedAt = data.getCompletedAt() - - Text( - data.getName(), - style = MaterialTheme.typography.titleLarge, - fontSize = nameFontSize, - ) - - Spacer(modifier = Modifier.weight(1f)) + Column( + verticalArrangement = Arrangement.spacedBy(2.dp), + modifier = Modifier.weight(1f), + ) { + Text( + data.getName(), + style = MaterialTheme.typography.titleLarge, + ) + if (description.isNotBlank()) { + Text( + description, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + ) + } + } - // TODO: removed in Phase 2A-2 — scanState/customerReadAt column dropped with ItemTag schema v2 + Spacer(modifier = Modifier.padding(horizontal = 8.dp)) Column( horizontalAlignment = Alignment.End, + verticalArrangement = Arrangement.spacedBy(4.dp), + modifier = Modifier.widthIn(min = 82.dp), ) { - data.getItemTagState()?.let { itemTagState -> - when (itemTagState) { - ItemTagState.Completed -> { - CompletedTag() - + when (state) { + ItemTagState.Completed -> { + CompletedTag() + if (completedAt.isNotBlank()) { Text( completedAt.cardDateTimeString(), + style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier - .padding(top = 4.dp), - fontSize = timestampFontSize, ) } - else -> { - IdlingTag() - } } + ItemTagState.Idled -> IdlingTag() + null -> Unit } } } From ca30aa66c5c298f30a7a43b8ecc8c9b070955f6d Mon Sep 17 00:00:00 2001 From: dadachi Date: Tue, 28 Apr 2026 15:33:25 +0900 Subject: [PATCH 2/2] Move description from ShopDetailCardView to ItemTagListCardView Drop description block from ShopDetailCardView and revert to the flatter row layout. Restructure ItemTagListCardView from ListItem to a manual Row with a 2-column layout that surfaces the description. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../ui/shop_detail/ShopDetailCardView.kt | 62 +++++++--------- .../item_tag_list/ItemTagListCardView.kt | 74 +++++++++---------- 2 files changed, 61 insertions(+), 75 deletions(-) diff --git a/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailCardView.kt b/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailCardView.kt index 57cb2aa..d39fce9 100644 --- a/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailCardView.kt +++ b/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_detail/ShopDetailCardView.kt @@ -1,17 +1,14 @@ package com.nativeapptemplate.nativeapptemplatefree.ui.shop_detail -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.widthIn import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp import com.nativeapptemplate.nativeapptemplatefree.model.Data import com.nativeapptemplate.nativeapptemplatefree.model.ItemTagState @@ -23,54 +20,45 @@ import com.nativeapptemplate.nativeapptemplatefree.utils.DateUtility.cardDateTim fun ShopDetailCardView( data: Data, ) { - val description = data.getDescription() - val state = data.getItemTagState() - val completedAt = data.getCompletedAt() - Row( - horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(16.dp), ) { - Column( - verticalArrangement = Arrangement.spacedBy(2.dp), - modifier = Modifier.weight(1f), - ) { - Text( - data.getName(), - style = MaterialTheme.typography.titleLarge, - ) - if (description.isNotBlank()) { - Text( - description, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 2, - overflow = TextOverflow.Ellipsis, - ) - } - } + val nameFontSize = with(LocalDensity.current) { MaterialTheme.typography.titleLarge.fontSize.value.dp.toSp() } + val timestampFontSize = with(LocalDensity.current) { MaterialTheme.typography.bodySmall.fontSize.value.dp.toSp() } + val completedAt = data.getCompletedAt() + + Text( + data.getName(), + style = MaterialTheme.typography.titleLarge, + fontSize = nameFontSize, + modifier = Modifier + .weight(1f) + .padding(end = 8.dp), + ) - Spacer(modifier = Modifier.padding(horizontal = 8.dp)) + // TODO: removed in Phase 2A-2 — scanState/customerReadAt column dropped with ItemTag schema v2 Column( horizontalAlignment = Alignment.End, - verticalArrangement = Arrangement.spacedBy(4.dp), - modifier = Modifier.widthIn(min = 82.dp), ) { - when (state) { - ItemTagState.Completed -> { - CompletedTag() - if (completedAt.isNotBlank()) { + data.getItemTagState()?.let { itemTagState -> + when (itemTagState) { + ItemTagState.Completed -> { + CompletedTag() + Text( completedAt.cardDateTimeString(), - style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier + .padding(top = 4.dp), + fontSize = timestampFontSize, ) } + else -> { + IdlingTag() + } } - ItemTagState.Idled -> IdlingTag() - null -> Unit } } } diff --git a/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagListCardView.kt b/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagListCardView.kt index 9e408cd..9bc2c82 100644 --- a/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagListCardView.kt +++ b/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/shop_settings/item_tag_list/ItemTagListCardView.kt @@ -5,7 +5,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.material3.ListItem +import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -28,40 +28,40 @@ fun ItemTagListCardView( val state = data.getItemTagState() val completedAt = data.getCompletedAt() - ListItem( - headlineContent = { - Row( - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth(), - ) { + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .clickable { onItemClick(data.id!!) } + .padding(horizontal = 16.dp, vertical = 12.dp), + ) { + Column( + modifier = Modifier.weight(1f), + verticalArrangement = Arrangement.spacedBy(2.dp), + ) { + Text( + data.getName(), + style = MaterialTheme.typography.titleMedium, + ) + if (description.isNotBlank()) { Text( - data.getName(), - style = MaterialTheme.typography.titleMedium, - modifier = Modifier.weight(1f), + description, + style = MaterialTheme.typography.bodySmall, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + color = MaterialTheme.colorScheme.onSurfaceVariant, ) - when (state) { - ItemTagState.Completed -> CompletedTag() - ItemTagState.Idled -> IdlingTag() - null -> Unit - } } - }, - supportingContent = if (description.isBlank() && state != ItemTagState.Completed) { - null - } else { - { - Column(verticalArrangement = Arrangement.spacedBy(2.dp)) { - if (description.isNotBlank()) { - Text( - description, - style = MaterialTheme.typography.bodySmall, - maxLines = 2, - overflow = TextOverflow.Ellipsis, - color = MaterialTheme.colorScheme.onSurfaceVariant, - ) - } - if (state == ItemTagState.Completed && completedAt.isNotBlank()) { + } + Column( + horizontalAlignment = Alignment.End, + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + when (state) { + ItemTagState.Completed -> { + CompletedTag() + if (completedAt.isNotBlank()) { Text( completedAt.cardDateTimeString(), style = MaterialTheme.typography.bodySmall, @@ -69,11 +69,9 @@ fun ItemTagListCardView( ) } } + ItemTagState.Idled -> IdlingTag() + null -> Unit } - }, - modifier = Modifier - .clickable { - onItemClick(data.id!!) - }, - ) + } + } }