Skip to content

Commit

Permalink
fix(android): limit max width of widgets for large screens and adjust…
Browse files Browse the repository at this point in the history
… alignment
  • Loading branch information
autoreleasefool committed Jun 20, 2024
1 parent 0e237a7 commit a44ccdb
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 94 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package ca.josephroque.bowlingcompanion.feature.statisticswidget.ui.layout

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredWidthIn
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
Expand All @@ -31,37 +33,43 @@ fun StatisticsWidgetLayout(
onAction: (StatisticsWidgetLayoutUiAction) -> Unit,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier.fillMaxWidth(),
) {
if (state.widgets.isEmpty()) {
StatisticsWidgetPlaceholderCard(onClick = {
onAction(StatisticsWidgetLayoutUiAction.ChangeLayoutClicked)
})
} else {
val widgetsRows = state.widgets.chunked(2)
widgetsRows.forEach { row ->
StatisticsWidgetRow(
widgets = row,
widgetCharts = state.widgetCharts,
onAction = onAction,
modifier = Modifier.padding(bottom = if (row == widgetsRows.last()) 0.dp else 16.dp),
BoxWithConstraints(modifier = modifier.fillMaxWidth()) {
val rowWidth = maxWidth
val numberOfWidgetsPerRow = (rowWidth / 240.dp).toInt().coerceAtLeast(2)

Column {
if (state.widgets.isEmpty()) {
StatisticsWidgetPlaceholderCard(
onClick = {
onAction(StatisticsWidgetLayoutUiAction.ChangeLayoutClicked)
},
)
}
} else {
val widgetsRows = state.widgets.chunked(numberOfWidgetsPerRow)
widgetsRows.forEach { row ->
StatisticsWidgetRow(
widgets = row,
widgetCharts = state.widgetCharts,
onAction = onAction,
modifier = Modifier.padding(bottom = if (row == widgetsRows.last()) 0.dp else 16.dp),
maxWidgetsPerRow = numberOfWidgetsPerRow,
)
}

Row {
Spacer(modifier = Modifier.weight(1f))
Row {
Spacer(modifier = Modifier.weight(1f))

Surface(
color = Color.Transparent,
shape = MaterialTheme.shapes.small,
onClick = { onAction(StatisticsWidgetLayoutUiAction.ChangeLayoutClicked) },
) {
Text(
stringResource(R.string.statistics_widget_layout_change),
style = MaterialTheme.typography.labelSmall,
modifier = Modifier.padding(8.dp),
)
Surface(
color = Color.Transparent,
shape = MaterialTheme.shapes.small,
onClick = { onAction(StatisticsWidgetLayoutUiAction.ChangeLayoutClicked) },
) {
Text(
stringResource(R.string.statistics_widget_layout_change),
style = MaterialTheme.typography.labelSmall,
modifier = Modifier.padding(8.dp),
)
}
}
}
}
Expand All @@ -70,6 +78,7 @@ fun StatisticsWidgetLayout(

@Composable
private fun StatisticsWidgetRow(
maxWidgetsPerRow: Int,
widgets: List<StatisticsWidget>,
widgetCharts: Map<UUID, StatisticsWidgetLayoutUiState.ChartContent>,
onAction: (StatisticsWidgetLayoutUiAction) -> Unit,
Expand All @@ -87,9 +96,16 @@ private fun StatisticsWidgetRow(
chart = chart?.chart,
chartEntryModelProducer = chart?.modelProducer,
onClick = { onAction(StatisticsWidgetLayoutUiAction.WidgetClicked(widget)) },
modifier = Modifier
.weight(1f)
.aspectRatio(if (widgets.size == 1) 2f else 1f),
modifier = if (maxWidgetsPerRow == 2) {
Modifier
.weight(1f)
.aspectRatio(if (widgets.size == 1) 2f else 1f)
} else {
Modifier
.requiredWidthIn(max = 240.dp)
.weight(1f, fill = false)
.aspectRatio(1f)
},
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ca.josephroque.bowlingcompanion.feature.statisticswidget.ui.layout.edito

import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
Expand Down Expand Up @@ -53,80 +54,85 @@ fun StatisticsWidgetLayoutEditor(
},
)

LazyVerticalGrid(
columns = GridCells.Fixed(2),
state = reorderableState.gridState,
modifier = modifier
.reorderable(reorderableState)
.detectReorderAfterLongPress(reorderableState)
.padding(horizontal = 8.dp),
) {
items(
state.widgets,
key = { it.id },
) { widget ->
ReorderableItem(
reorderableState = reorderableState,
key = widget.id,
) { isDragging ->
val elevation = animateDpAsState(if (isDragging) 16.dp else 0.dp, label = "elevation")
BoxWithConstraints {
val rowWidth = maxWidth
val numberOfWidgetsPerRow = (rowWidth / 240.dp).toInt().coerceAtLeast(2)

Wiggle { modifier ->
Box(
contentAlignment = Alignment.TopEnd,
modifier = modifier,
) {
val chart = state.widgetCharts[widget.id]
LazyVerticalGrid(
columns = GridCells.Fixed(numberOfWidgetsPerRow),
state = reorderableState.gridState,
modifier = modifier
.reorderable(reorderableState)
.detectReorderAfterLongPress(reorderableState)
.padding(horizontal = 8.dp),
) {
items(
state.widgets,
key = { it.id },
) { widget ->
ReorderableItem(
reorderableState = reorderableState,
key = widget.id,
) { isDragging ->
val elevation = animateDpAsState(if (isDragging) 16.dp else 0.dp, label = "elevation")

StatisticsWidgetCard(
widget = widget,
chart = chart?.chart,
chartEntryModelProducer = chart?.modelProducer,
onClick = { onAction(StatisticsWidgetLayoutEditorUiAction.WidgetClicked(widget)) },
modifier = Modifier
.aspectRatio(1f)
.padding(8.dp)
.shadow(elevation.value),
)
Wiggle { modifier ->
Box(
contentAlignment = Alignment.TopEnd,
modifier = modifier,
) {
val chart = state.widgetCharts[widget.id]

if (state.isDeleteModeEnabled) {
IconButton(
StatisticsWidgetCard(
widget = widget,
chart = chart?.chart,
chartEntryModelProducer = chart?.modelProducer,
onClick = { onAction(StatisticsWidgetLayoutEditorUiAction.WidgetClicked(widget)) },
colors = IconButtonDefaults.filledIconButtonColors(
contentColor = colorResource(
ca.josephroque.bowlingcompanion.core.designsystem.R.color.white,
),
containerColor = colorResource(
ca.josephroque.bowlingcompanion.core.designsystem.R.color.destructive,
modifier = Modifier
.aspectRatio(1f)
.padding(8.dp)
.shadow(elevation.value),
)

if (state.isDeleteModeEnabled) {
IconButton(
onClick = { onAction(StatisticsWidgetLayoutEditorUiAction.WidgetClicked(widget)) },
colors = IconButtonDefaults.filledIconButtonColors(
contentColor = colorResource(
ca.josephroque.bowlingcompanion.core.designsystem.R.color.white,
),
containerColor = colorResource(
ca.josephroque.bowlingcompanion.core.designsystem.R.color.destructive,
),
),
),
) {
Icon(
Icons.Default.Delete,
contentDescription = stringResource(R.string.cd_delete_widget),
)
) {
Icon(
Icons.Default.Delete,
contentDescription = stringResource(R.string.cd_delete_widget),
)
}
}
}
}
}
}
}

item(span = { GridItemSpan(2) }) {
Text(
text = stringResource(
if (state.isDeleteModeEnabled) {
R.string.statistics_widget_layout_editor_tap_to_delete_widget
} else {
R.string.statistics_widget_layout_editor_tap_and_hold_to_reorder
},
),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
)
item(span = { GridItemSpan(2) }) {
Text(
text = stringResource(
if (state.isDeleteModeEnabled) {
R.string.statistics_widget_layout_editor_tap_to_delete_widget
} else {
R.string.statistics_widget_layout_editor_tap_and_hold_to_reorder
},
),
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
)
}
}
}
}
Expand Down

0 comments on commit a44ccdb

Please sign in to comment.