Skip to content

Commit cf30a7e

Browse files
authored
Adapt PC connection rows for small screens
- Extend preference row components to support runtime text and optional below-row content - Switch PC connection rows to PreferenceComponentBase for consistent row styling - Move PC row actions below text on compact widths to avoid squishing names and summaries 🤖 Auto-generated
1 parent ad91292 commit cf30a7e

3 files changed

Lines changed: 141 additions & 49 deletions

File tree

app/src/main/java/com/enaboapps/switchify/components/PreferenceComponentBase.kt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,31 @@ import com.enaboapps.switchify.R
1919

2020
@Composable
2121
fun PreferenceComponentBase(
22-
titleResId: Int,
23-
summaryResId: Int,
22+
titleResId: Int? = null,
23+
summaryResId: Int? = null,
24+
runtimeTitle: String? = null,
25+
runtimeSummary: String? = null,
2426
explanationResId: Int? = null,
2527
leadingIcon: ImageVector? = null,
2628
onClick: (() -> Unit)? = null,
27-
trailing: @Composable () -> Unit
29+
trailing: @Composable () -> Unit = {},
30+
belowContent: (@Composable () -> Unit)? = null
2831
) {
32+
val title = runtimeTitle ?: titleResId?.let { stringResource(it) }.orEmpty()
33+
val summary = runtimeSummary ?: summaryResId?.let { stringResource(it) }.orEmpty()
34+
2935
PreferenceRowScaffold(
30-
title = stringResource(titleResId),
31-
summary = stringResource(summaryResId),
36+
title = title,
37+
summary = summary,
3238
onClick = onClick,
3339
leadingContent = leadingIcon?.let {
3440
{
3541
PreferenceRowLeadingIcon(imageVector = it)
3642
}
37-
}
43+
},
44+
belowContent = belowContent
3845
) {
39-
if (explanationResId != null) {
46+
if (titleResId != null && explanationResId != null) {
4047
ExplanationButton(titleResId = titleResId, explanationResId = explanationResId)
4148
}
4249
trailing()

app/src/main/java/com/enaboapps/switchify/components/PreferenceRowScaffold.kt

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ fun PreferenceRowScaffold(
3434
enabled: Boolean = true,
3535
onClick: (() -> Unit)? = null,
3636
leadingContent: (@Composable () -> Unit)? = null,
37+
belowContent: (@Composable () -> Unit)? = null,
3738
trailing: @Composable RowScope.() -> Unit
3839
) {
3940
val scheme = MaterialTheme.colorScheme
@@ -44,28 +45,65 @@ fun PreferenceRowScaffold(
4445
.let { if (onClick != null) it.clickable(enabled = enabled, onClick = onClick) else it }
4546
.padding(Dimens.spaceM)
4647

47-
Row(
48-
modifier = rowModifier,
49-
horizontalArrangement = Arrangement.spacedBy(Dimens.spaceM),
50-
verticalAlignment = Alignment.CenterVertically
51-
) {
52-
leadingContent?.invoke()
53-
Column(modifier = Modifier.weight(1f)) {
54-
Text(
55-
text = title,
56-
style = MaterialTheme.typography.titleMedium,
57-
maxLines = 2,
58-
overflow = TextOverflow.Ellipsis
59-
)
60-
Text(
61-
text = summary,
62-
style = MaterialTheme.typography.bodySmall,
63-
color = scheme.onSurfaceVariant,
64-
maxLines = 3,
65-
overflow = TextOverflow.Ellipsis
48+
if (belowContent == null) {
49+
Row(
50+
modifier = rowModifier,
51+
horizontalArrangement = Arrangement.spacedBy(Dimens.spaceM),
52+
verticalAlignment = Alignment.CenterVertically
53+
) {
54+
PreferenceRowText(
55+
title = title,
56+
summary = summary,
57+
modifier = Modifier.weight(1f),
58+
leadingContent = leadingContent
6659
)
60+
trailing()
61+
}
62+
} else {
63+
Column(
64+
modifier = rowModifier,
65+
verticalArrangement = Arrangement.spacedBy(Dimens.spaceS)
66+
) {
67+
Row(
68+
modifier = Modifier.fillMaxWidth(),
69+
horizontalArrangement = Arrangement.spacedBy(Dimens.spaceM),
70+
verticalAlignment = Alignment.CenterVertically
71+
) {
72+
PreferenceRowText(
73+
title = title,
74+
summary = summary,
75+
modifier = Modifier.weight(1f),
76+
leadingContent = leadingContent
77+
)
78+
trailing()
79+
}
80+
belowContent()
6781
}
68-
trailing()
82+
}
83+
}
84+
85+
@Composable
86+
private fun PreferenceRowText(
87+
title: String,
88+
summary: String,
89+
modifier: Modifier = Modifier,
90+
leadingContent: (@Composable () -> Unit)? = null
91+
) {
92+
leadingContent?.invoke()
93+
Column(modifier = modifier) {
94+
Text(
95+
text = title,
96+
style = MaterialTheme.typography.titleMedium,
97+
maxLines = 2,
98+
overflow = TextOverflow.Ellipsis
99+
)
100+
Text(
101+
text = summary,
102+
style = MaterialTheme.typography.bodySmall,
103+
color = MaterialTheme.colorScheme.onSurfaceVariant,
104+
maxLines = 3,
105+
overflow = TextOverflow.Ellipsis
106+
)
69107
}
70108
}
71109

app/src/main/java/com/enaboapps/switchify/screens/pc/PcConnectionScreen.kt

Lines changed: 69 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.enaboapps.switchify.screens.pc
22

33
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.BoxWithConstraints
45
import androidx.compose.foundation.layout.Column
56
import androidx.compose.foundation.layout.Row
67
import androidx.compose.foundation.layout.fillMaxWidth
@@ -20,11 +21,12 @@ import androidx.compose.ui.platform.LocalContext
2021
import androidx.compose.ui.res.stringResource
2122
import androidx.compose.ui.text.font.FontFamily
2223
import androidx.compose.ui.text.style.TextAlign
24+
import androidx.compose.ui.unit.dp
2325
import androidx.lifecycle.viewmodel.compose.viewModel
2426
import androidx.navigation.NavController
2527
import com.enaboapps.switchify.R
2628
import com.enaboapps.switchify.components.BaseView
27-
import com.enaboapps.switchify.components.PanelListRow
29+
import com.enaboapps.switchify.components.PreferenceComponentBase
2830
import com.enaboapps.switchify.components.ScrollableView
2931
import com.enaboapps.switchify.components.Section
3032
import com.enaboapps.switchify.pc.PcApprovalCodeState
@@ -33,6 +35,8 @@ import com.enaboapps.switchify.pc.PcRowState
3335
import com.enaboapps.switchify.pc.PcRowStatus
3436
import com.enaboapps.switchify.theme.Dimens
3537

38+
private val PcConnectionCompactRowWidth = 380.dp
39+
3640
@Composable
3741
fun PcConnectionScreen(navController: NavController) {
3842
val context = LocalContext.current
@@ -59,24 +63,12 @@ fun PcConnectionScreen(navController: NavController) {
5963
modifier = Modifier.padding(horizontal = Dimens.spaceM, vertical = Dimens.spaceS)
6064
)
6165
uiState.discoveredPcs.forEach { row ->
62-
PanelListRow(
63-
runtimeTitle = row.title,
64-
runtimeSummary = row.summary,
66+
PcConnectionPreferenceRow(
67+
title = row.title,
68+
summary = row.summary,
6569
onClick = { row.perform(viewModel) },
66-
trailing = {
67-
Row(horizontalArrangement = Arrangement.spacedBy(Dimens.spaceS)) {
68-
PcRowActionButton(
69-
text = row.actionText,
70-
enabled = row.enabled,
71-
connected = row.status == PcRowStatus.Connected,
72-
onClick = { row.perform(viewModel) }
73-
)
74-
if (row.canUnpair) {
75-
TextButton(onClick = { viewModel.requestUnpair(row.pc.desktopId, row.title) }) {
76-
Text(stringResource(R.string.pc_connection_unpair))
77-
}
78-
}
79-
}
70+
actions = {
71+
PcNearbyRowActions(row = row, viewModel = viewModel)
8072
}
8173
)
8274
}
@@ -86,11 +78,11 @@ fun PcConnectionScreen(navController: NavController) {
8678
Section(titleResId = R.string.pc_connection_paired_section) {
8779
Column(modifier = Modifier.padding(vertical = Dimens.spaceS)) {
8880
uiState.savedPairings.forEach { row ->
89-
PanelListRow(
90-
runtimeTitle = row.title,
91-
runtimeSummary = row.summary,
81+
PcConnectionPreferenceRow(
82+
title = row.title,
83+
summary = row.summary,
9284
onClick = { viewModel.requestUnpair(row.desktopId, row.title) },
93-
trailing = {
85+
actions = {
9486
TextButton(
9587
enabled = row.canUnpair,
9688
onClick = { viewModel.requestUnpair(row.desktopId, row.title) }
@@ -145,6 +137,61 @@ fun PcConnectionScreen(navController: NavController) {
145137
}
146138
}
147139

140+
@Composable
141+
private fun PcConnectionPreferenceRow(
142+
title: String,
143+
summary: String,
144+
onClick: () -> Unit,
145+
actions: @Composable () -> Unit
146+
) {
147+
BoxWithConstraints {
148+
val compact = maxWidth < PcConnectionCompactRowWidth
149+
150+
PreferenceComponentBase(
151+
runtimeTitle = title,
152+
runtimeSummary = summary,
153+
onClick = onClick,
154+
trailing = {
155+
if (!compact) {
156+
actions()
157+
}
158+
},
159+
belowContent = if (compact) {
160+
{
161+
Row(
162+
modifier = Modifier.fillMaxWidth(),
163+
horizontalArrangement = Arrangement.End
164+
) {
165+
actions()
166+
}
167+
}
168+
} else {
169+
null
170+
}
171+
)
172+
}
173+
}
174+
175+
@Composable
176+
private fun PcNearbyRowActions(
177+
row: PcRowState,
178+
viewModel: PcConnectionViewModel
179+
) {
180+
Row(horizontalArrangement = Arrangement.spacedBy(Dimens.spaceS)) {
181+
PcRowActionButton(
182+
text = row.actionText,
183+
enabled = row.enabled,
184+
connected = row.status == PcRowStatus.Connected,
185+
onClick = { row.perform(viewModel) }
186+
)
187+
if (row.canUnpair) {
188+
TextButton(onClick = { viewModel.requestUnpair(row.pc.desktopId, row.title) }) {
189+
Text(stringResource(R.string.pc_connection_unpair))
190+
}
191+
}
192+
}
193+
}
194+
148195
@Composable
149196
private fun PcApprovalCodeDialog(approvalCode: PcApprovalCodeState) {
150197
AlertDialog(

0 commit comments

Comments
 (0)