Skip to content

Commit 30268a3

Browse files
committed
Implement ProfileHeader composable
1 parent 60b3b9c commit 30268a3

File tree

2 files changed

+114
-3
lines changed

2 files changed

+114
-3
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package com.gravatar.app.homeUi.presentation.home.profile
2+
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.Row
6+
import androidx.compose.foundation.layout.Spacer
7+
import androidx.compose.foundation.layout.padding
8+
import androidx.compose.foundation.layout.width
9+
import androidx.compose.foundation.shape.CircleShape
10+
import androidx.compose.material3.MaterialTheme
11+
import androidx.compose.material3.Text
12+
import androidx.compose.runtime.Composable
13+
import androidx.compose.ui.Alignment
14+
import androidx.compose.ui.Modifier
15+
import androidx.compose.ui.draw.clip
16+
import androidx.compose.ui.text.font.FontWeight
17+
import androidx.compose.ui.tooling.preview.Preview
18+
import androidx.compose.ui.unit.dp
19+
import com.gravatar.extensions.defaultProfile
20+
import com.gravatar.restapi.models.Profile
21+
import com.gravatar.ui.components.atomic.Avatar
22+
23+
@Composable
24+
fun ProfileHeader(
25+
profile: Profile,
26+
modifier: Modifier = Modifier
27+
) {
28+
Row(
29+
modifier = modifier,
30+
horizontalArrangement = Arrangement.Start,
31+
verticalAlignment = Alignment.CenterVertically
32+
) {
33+
Avatar(
34+
profile = profile,
35+
size = 44.dp,
36+
modifier = Modifier.clip(CircleShape),
37+
)
38+
39+
Spacer(modifier = Modifier.width(16.dp))
40+
41+
Column {
42+
Text(
43+
text = profile.displayName,
44+
style = MaterialTheme.typography.titleMedium,
45+
fontWeight = FontWeight.Bold
46+
)
47+
48+
profile.jobInfo().takeIf { it.isNotBlank() }?.let { jobInfo ->
49+
Text(
50+
text = jobInfo,
51+
style = MaterialTheme.typography.bodyMedium,
52+
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
53+
)
54+
}
55+
}
56+
}
57+
}
58+
59+
private fun Profile.jobInfo(): String {
60+
return buildString {
61+
if (jobTitle.isNotBlank()) {
62+
append(jobTitle)
63+
}
64+
if (company.isNotBlank()) {
65+
if (isNotEmpty()) append(", ")
66+
append(company)
67+
}
68+
}
69+
}
70+
71+
@Preview(showBackground = true, name = "Both job title and company")
72+
@Composable
73+
fun ProfileHeaderPreviewBoth() {
74+
ProfileHeader(
75+
profile = defaultProfile(
76+
hash = "",
77+
displayName = "John Doe",
78+
jobTitle = "Software Engineer",
79+
company = "Automattic"
80+
),
81+
modifier = Modifier.padding(16.dp)
82+
)
83+
}
84+
85+
@Preview(showBackground = true, name = "Only job title")
86+
@Composable
87+
fun ProfileHeaderPreviewJobOnly() {
88+
ProfileHeader(
89+
profile = defaultProfile(hash = "", displayName = "John Doe", jobTitle = "Software Engineer", company = ""),
90+
modifier = Modifier.padding(16.dp)
91+
)
92+
}
93+
94+
@Preview(showBackground = true, name = "Only company")
95+
@Composable
96+
fun ProfileHeaderPreviewCompanyOnly() {
97+
ProfileHeader(
98+
profile = defaultProfile(hash = "", displayName = "John Doe", jobTitle = "", company = "Automattic"),
99+
modifier = Modifier.padding(16.dp)
100+
)
101+
}
102+
103+
@Preview(showBackground = true, name = "Neither job title nor company")
104+
@Composable
105+
fun ProfileHeaderPreviewNeither() {
106+
ProfileHeader(
107+
profile = defaultProfile(hash = "", displayName = "John Doe", jobTitle = "", company = ""),
108+
modifier = Modifier.padding(16.dp)
109+
)
110+
}

homeUi/src/main/kotlin/com/gravatar/app/homeUi/presentation/home/profile/ProfileScreen.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ package com.gravatar.app.homeUi.presentation.home.profile
22

33
import androidx.compose.foundation.layout.Box
44
import androidx.compose.foundation.layout.fillMaxSize
5+
import androidx.compose.foundation.layout.padding
56
import androidx.compose.material3.CircularProgressIndicator
67
import androidx.compose.material3.Text
78
import androidx.compose.runtime.Composable
89
import androidx.compose.runtime.collectAsState
910
import androidx.compose.runtime.getValue
1011
import androidx.compose.ui.Alignment
1112
import androidx.compose.ui.Modifier
13+
import androidx.compose.ui.unit.dp
1214
import org.koin.androidx.compose.koinViewModel
1315

1416
@Composable
@@ -17,14 +19,13 @@ fun ProfileScreen(viewModel: ProfileViewModel = koinViewModel()) {
1719

1820
Box(
1921
modifier = Modifier.fillMaxSize(),
20-
contentAlignment = Alignment.Center
2122
) {
2223
if (uiState.isLoading) {
23-
CircularProgressIndicator()
24+
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
2425
} else {
2526
uiState.profile.let { profile ->
2627
if (profile != null) {
27-
Text(profile.displayName)
28+
ProfileHeader(profile = profile, modifier = Modifier.padding(16.dp))
2829
} else {
2930
Text("There was an error retrieving the profile.")
3031
}

0 commit comments

Comments
 (0)