Skip to content

Commit dbef915

Browse files
committed
feat: make project card layout responsive
1 parent deeaf85 commit dbef915

File tree

2 files changed

+107
-51
lines changed

2 files changed

+107
-51
lines changed

composeApp/src/wasmJsMain/kotlin/org/nsh07/nsh07/ui/homeScreen/HomeScreenContent.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ fun LazyListScope.mainContent(
127127
ProjectCard(
128128
project = it,
129129
cardPadding = cardPadding,
130+
wide = wide,
130131
modifier = Modifier.padding(bottom = 32.dp)
131132
)
132133
}

composeApp/src/wasmJsMain/kotlin/org/nsh07/nsh07/ui/homeScreen/ProjectCard.kt

Lines changed: 106 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ import androidx.compose.material3.MaterialTheme.shapes
1111
import androidx.compose.material3.MaterialTheme.typography
1212
import androidx.compose.material3.Text
1313
import androidx.compose.runtime.Composable
14+
import androidx.compose.runtime.remember
1415
import androidx.compose.ui.Alignment
1516
import androidx.compose.ui.Modifier
1617
import androidx.compose.ui.draw.clip
18+
import androidx.compose.ui.graphics.Shape
1719
import androidx.compose.ui.layout.ContentScale
1820
import androidx.compose.ui.platform.LocalUriHandler
1921
import androidx.compose.ui.text.font.FontWeight
@@ -32,69 +34,122 @@ import org.nsh07.nsh07.network.Repo
3234
fun ProjectCard(
3335
project: Repo,
3436
cardPadding: Dp,
37+
wide: Boolean,
3538
modifier: Modifier = Modifier,
3639
imageUri: String? = null,
3740
description: String? = null,
3841
) {
39-
val colorScheme = colorScheme
42+
val shapes = shapes
4043
val uriHandler = LocalUriHandler.current
4144

45+
val imageShape = remember(wide) { if (wide) shapes.medium else shapes.large }
46+
4247
Box(
4348
modifier
4449
.clip(shapes.largeIncreased)
4550
.clickable { uriHandler.openUri(project.htmlUrl) }
4651
) {
47-
Row(Modifier.fillMaxWidth().padding(cardPadding)) {
48-
SubcomposeAsyncImage(
49-
model = imageUri
50-
?: "https://raw.githubusercontent.com/${project.fullName}/refs/heads/main/fastlane/metadata/android/en-US/images/featureGraphic.png",
51-
contentDescription = null,
52-
contentScale = ContentScale.Crop,
53-
modifier = Modifier.padding(top = 4.dp, end = 16.dp).weight(1f).clip(shapes.large),
54-
loading = {
55-
Box(Modifier.fillMaxWidth().aspectRatio(2f)) {
56-
CircularWavyProgressIndicator(Modifier.align(Alignment.Center))
57-
}
58-
},
59-
error = {
60-
Box(Modifier.fillMaxWidth().aspectRatio(2f).border(1.dp, colorScheme.outline, shapes.large))
61-
}
62-
)
63-
Column(Modifier.weight(3f)) {
64-
FlowRow(itemVerticalAlignment = Alignment.CenterVertically) {
65-
Text(project.name, style = typography.bodyLarge, fontWeight = FontWeight.Medium)
66-
Icon(
67-
painterResource(Res.drawable.open_in_browser),
68-
null,
69-
modifier = Modifier.padding(start = 4.dp).size(16.dp)
70-
)
71-
}
72-
Text(
73-
description ?: project.description,
74-
style = typography.bodyMedium,
75-
color = colorScheme.onSurfaceVariant,
76-
modifier = Modifier.padding(top = 8.dp)
52+
if (wide) {
53+
Row(Modifier.fillMaxWidth().padding(cardPadding)) {
54+
ProjectThumbnail(
55+
project,
56+
imageShape,
57+
wide,
58+
Modifier.weight(1f),
59+
imageUri
60+
)
61+
ProjectMainContent(
62+
project,
63+
description,
64+
Modifier.weight(3f)
7765
)
78-
Row(
79-
verticalAlignment = Alignment.CenterVertically,
80-
horizontalArrangement = Arrangement.spacedBy(4.dp),
81-
modifier = Modifier.padding(top = 8.dp)
82-
) {
83-
Icon(
84-
painterResource(Res.drawable.star),
85-
null
86-
)
87-
Text(project.stargazersCount.toString(), style = typography.labelLarge)
88-
Spacer(Modifier.width(8.dp))
89-
Icon(
90-
painterResource(Res.drawable.fork),
91-
null,
92-
modifier = Modifier.size(20.dp)
93-
)
94-
Text(project.forksCount.toString(), style = typography.labelLarge)
95-
}
96-
LabelRow(project.topics, Modifier.padding(top = 16.dp))
9766
}
67+
} else {
68+
Column(Modifier.fillMaxWidth().padding(cardPadding)) {
69+
ProjectThumbnail(
70+
project,
71+
imageShape,
72+
wide,
73+
imageUri = imageUri
74+
)
75+
ProjectMainContent(project, description)
76+
}
77+
}
78+
}
79+
}
80+
81+
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
82+
@Composable
83+
fun ProjectThumbnail(
84+
project: Repo,
85+
imageShape: Shape,
86+
wide: Boolean,
87+
modifier: Modifier = Modifier,
88+
imageUri: String? = null
89+
) {
90+
SubcomposeAsyncImage(
91+
model = imageUri
92+
?: "https://raw.githubusercontent.com/${project.fullName}/refs/heads/main/fastlane/metadata/android/en-US/images/featureGraphic.png",
93+
contentDescription = null,
94+
contentScale = ContentScale.Crop,
95+
modifier = Modifier
96+
.padding(
97+
top = if (wide) 4.dp else 0.dp,
98+
end = if (wide) 16.dp else 0.dp,
99+
bottom = if (!wide) 8.dp else 0.dp
100+
)
101+
.then(modifier)
102+
.clip(imageShape),
103+
loading = {
104+
Box(Modifier.fillMaxWidth().aspectRatio(2f)) {
105+
CircularWavyProgressIndicator(Modifier.align(Alignment.Center))
106+
}
107+
},
108+
error = {
109+
if (wide) Box(Modifier.fillMaxWidth().aspectRatio(2f).border(1.dp, colorScheme.outline, imageShape))
110+
}
111+
)
112+
}
113+
114+
@Composable
115+
fun ProjectMainContent(
116+
project: Repo,
117+
description: String? = null,
118+
modifier: Modifier = Modifier
119+
) {
120+
Column(modifier) {
121+
FlowRow(itemVerticalAlignment = Alignment.CenterVertically) {
122+
Text(project.name, style = typography.bodyLarge, fontWeight = FontWeight.Medium)
123+
Icon(
124+
painterResource(Res.drawable.open_in_browser),
125+
null,
126+
modifier = Modifier.padding(start = 4.dp).size(16.dp)
127+
)
128+
}
129+
Text(
130+
description ?: project.description,
131+
style = typography.bodyMedium,
132+
color = colorScheme.onSurfaceVariant,
133+
modifier = Modifier.padding(top = 8.dp)
134+
)
135+
Row(
136+
verticalAlignment = Alignment.CenterVertically,
137+
horizontalArrangement = Arrangement.spacedBy(4.dp),
138+
modifier = Modifier.padding(top = 8.dp)
139+
) {
140+
Icon(
141+
painterResource(Res.drawable.star),
142+
null
143+
)
144+
Text(project.stargazersCount.toString(), style = typography.labelLarge)
145+
Spacer(Modifier.width(8.dp))
146+
Icon(
147+
painterResource(Res.drawable.fork),
148+
null,
149+
modifier = Modifier.size(20.dp)
150+
)
151+
Text(project.forksCount.toString(), style = typography.labelLarge)
98152
}
153+
LabelRow(project.topics, Modifier.padding(top = 16.dp))
99154
}
100-
}
155+
}

0 commit comments

Comments
 (0)