16
16
package io.getstream.feeds.android.sample.profile
17
17
18
18
import androidx.compose.foundation.BorderStroke
19
- import androidx.compose.foundation.clickable
20
19
import androidx.compose.foundation.layout.Arrangement
21
20
import androidx.compose.foundation.layout.Column
22
21
import androidx.compose.foundation.layout.Row
23
22
import androidx.compose.foundation.layout.fillMaxSize
24
23
import androidx.compose.foundation.layout.fillMaxWidth
25
24
import androidx.compose.foundation.layout.padding
26
25
import androidx.compose.foundation.layout.systemBarsPadding
27
- import androidx.compose.foundation.lazy.LazyColumn
28
- import androidx.compose.foundation.lazy.items
26
+ import androidx.compose.foundation.rememberScrollState
29
27
import androidx.compose.foundation.shape.CircleShape
30
- import androidx.compose.material3.Card
31
- import androidx.compose.material3.CardDefaults
28
+ import androidx.compose.foundation.verticalScroll
32
29
import androidx.compose.material3.HorizontalDivider
30
+ import androidx.compose.material3.LocalMinimumInteractiveComponentSize
31
+ import androidx.compose.material3.MaterialTheme
32
+ import androidx.compose.material3.OutlinedButton
33
+ import androidx.compose.material3.Surface
33
34
import androidx.compose.material3.Text
35
+ import androidx.compose.material3.TextButton
34
36
import androidx.compose.runtime.Composable
37
+ import androidx.compose.runtime.CompositionLocalProvider
35
38
import androidx.compose.runtime.LaunchedEffect
36
39
import androidx.compose.runtime.getValue
37
40
import androidx.compose.ui.Alignment
@@ -70,21 +73,23 @@ fun ProfileScreen(navigator: DestinationsNavigator) {
70
73
71
74
val state by viewModel.state.collectAsStateWithLifecycle()
72
75
73
- when (val state = state) {
74
- AsyncResource .Loading -> LoadingScreen ()
76
+ Surface {
77
+ when (val state = state) {
78
+ AsyncResource .Loading -> LoadingScreen ()
75
79
76
- AsyncResource .Error -> {
77
- LaunchedEffect (Unit ) { navigator.popBackStack() }
78
- return
79
- }
80
+ AsyncResource .Error -> {
81
+ LaunchedEffect (Unit ) { navigator.popBackStack() }
82
+ return @Surface
83
+ }
80
84
81
- is AsyncResource .Content ->
82
- ProfileScreen (
83
- state = state.data,
84
- followSuggestions = viewModel.followSuggestions,
85
- onFollowClick = viewModel::follow,
86
- onUnfollowClick = viewModel::unfollow,
87
- )
85
+ is AsyncResource .Content ->
86
+ ProfileScreen (
87
+ state = state.data,
88
+ followSuggestions = viewModel.followSuggestions,
89
+ onFollowClick = viewModel::follow,
90
+ onUnfollowClick = viewModel::unfollow,
91
+ )
92
+ }
88
93
}
89
94
}
90
95
@@ -95,7 +100,12 @@ fun ProfileScreen(
95
100
onFollowClick : (FeedId ) -> Unit ,
96
101
onUnfollowClick : (FeedId ) -> Unit ,
97
102
) {
98
- Column (modifier = Modifier .fillMaxSize().systemBarsPadding().padding(16 .dp)) {
103
+ val scrollState = rememberScrollState()
104
+
105
+ Column (
106
+ modifier =
107
+ Modifier .fillMaxSize().systemBarsPadding().verticalScroll(scrollState).padding(16 .dp)
108
+ ) {
99
109
Text (
100
110
text = " Profile" ,
101
111
fontSize = 24 .sp,
@@ -154,14 +164,12 @@ fun ProfileScreen(
154
164
val followSuggestions by followSuggestions.collectAsStateWithLifecycle()
155
165
SectionTitle (" Who to follow" )
156
166
if (followSuggestions.isNotEmpty()) {
157
- LazyColumn {
158
- items(followSuggestions) {
159
- FollowSuggestionItem (
160
- owner = it.createdBy,
161
- fid = it.fid,
162
- onFollowClick = onFollowClick,
163
- )
164
- }
167
+ followSuggestions.forEach {
168
+ FollowSuggestionItem (
169
+ owner = it.createdBy,
170
+ fid = it.fid,
171
+ onFollowClick = onFollowClick,
172
+ )
165
173
}
166
174
} else {
167
175
Text (text = " -No follow suggestions-" )
@@ -191,7 +199,7 @@ private fun <T> ProfileSection(
191
199
if (items.isNotEmpty()) {
192
200
items.forEach { item -> itemContent(item) }
193
201
} else {
194
- Text (text = emptyText, color = Color . Gray )
202
+ Text (text = emptyText, color = MaterialTheme .colorScheme.onSurfaceVariant )
195
203
}
196
204
197
205
HorizontalDivider (Modifier .fillMaxWidth().padding(vertical = 16 .dp))
@@ -200,20 +208,20 @@ private fun <T> ProfileSection(
200
208
@Composable
201
209
fun FollowingItem (follow : FollowData , onUnfollowClick : (FeedId ) -> Unit ) {
202
210
Row (
203
- modifier = Modifier .fillMaxWidth().padding(vertical = 4 .dp) ,
211
+ modifier = Modifier .fillMaxWidth(),
204
212
horizontalArrangement = Arrangement .SpaceBetween ,
213
+ verticalAlignment = Alignment .CenterVertically ,
205
214
) {
206
215
Text (
207
216
text = follow.targetFeed.createdBy.run { name ? : id },
208
217
fontSize = 16 .sp,
209
218
fontWeight = FontWeight .Bold ,
210
219
)
211
- Text (
212
- modifier = Modifier .clickable { onUnfollowClick(follow.targetFeed.fid) },
213
- text = " Unfollow" ,
214
- fontSize = 14 .sp,
215
- color = Color .Blue ,
216
- )
220
+ CompositionLocalProvider (LocalMinimumInteractiveComponentSize provides 0 .dp) {
221
+ TextButton (onClick = { onUnfollowClick(follow.targetFeed.fid) }) {
222
+ Text (text = " Unfollow" )
223
+ }
224
+ }
217
225
}
218
226
}
219
227
@@ -237,19 +245,13 @@ fun FollowSuggestionItem(owner: UserData, fid: FeedId, onFollowClick: (FeedId) -
237
245
)
238
246
}
239
247
}
240
- Card (
248
+ OutlinedButton (
241
249
modifier = Modifier .padding(start = 8 .dp).align(Alignment .CenterVertically ),
242
250
shape = CircleShape ,
243
251
border = BorderStroke (1 .dp, Color .Gray ),
244
- colors = CardDefaults .cardColors(containerColor = Color .Transparent ),
245
252
onClick = { onFollowClick(fid) },
246
253
) {
247
- Text (
248
- text = " Follow" ,
249
- modifier = Modifier .padding(horizontal = 16 .dp, vertical = 8 .dp),
250
- fontSize = 14 .sp,
251
- color = Color .Blue ,
252
- )
254
+ Text (text = " Follow" )
253
255
}
254
256
}
255
257
}
0 commit comments