更新个人资料编辑功能

- 新增主页背景图编辑
- 优化个人资料编辑页面布局
This commit is contained in:
2024-08-28 16:40:09 +08:00
parent 07b89fe3cc
commit 65e348e704
11 changed files with 232 additions and 103 deletions

5
.idea/gradle.xml generated
View File

@@ -4,8 +4,11 @@
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" /> <option name="gradleHome" value="$PROJECT_DIR$/../.sdkman/candidates/gradle/8.9" />
<option name="gradleJvm" value="corretto-17" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />

View File

@@ -90,7 +90,5 @@ dependencies {
implementation("com.squareup.retrofit2:converter-gson:2.11.0") implementation("com.squareup.retrofit2:converter-gson:2.11.0")
implementation("androidx.credentials:credentials:1.2.2") implementation("androidx.credentials:credentials:1.2.2")
implementation("androidx.credentials:credentials-play-services-auth:1.2.2") implementation("androidx.credentials:credentials-play-services-auth:1.2.2")
} }

View File

@@ -36,7 +36,11 @@ data class AccountProfile(
// 粉丝数 // 粉丝数
val followerCount: Int, val followerCount: Int,
// 是否关注 // 是否关注
val isFollowing: Boolean val isFollowing: Boolean,
// 个人简介
val bio: String,
// 主页背景图
val banner: String?,
) { ) {
/** /**
* 转换为Entity * 转换为Entity
@@ -48,9 +52,10 @@ data class AccountProfile(
followingCount = followingCount, followingCount = followingCount,
nickName = nickname, nickName = nickname,
avatar = "${ApiClient.BASE_SERVER}$avatar", avatar = "${ApiClient.BASE_SERVER}$avatar",
bio = "", bio = bio,
country = "Worldwide", country = "Worldwide",
isFollowing = isFollowing isFollowing = isFollowing,
banner = "${ApiClient.BASE_SERVER}$banner"
) )
} }
} }
@@ -230,8 +235,14 @@ interface AccountService {
* @param avatar 头像 * @param avatar 头像
* @param nickName 昵称 * @param nickName 昵称
* @param bio 简介 * @param bio 简介
* @param banner 主页背景图
*/ */
suspend fun updateProfile(avatar: UploadImage?, nickName: String?, bio: String?) suspend fun updateProfile(
avatar: UploadImage?,
banner: UploadImage?,
nickName: String?,
bio: String?
)
/** /**
* 注册用户 * 注册用户
@@ -328,12 +339,21 @@ class AccountServiceImpl : AccountService {
return MultipartBody.Part.createFormData(name, filename, requestFile) return MultipartBody.Part.createFormData(name, filename, requestFile)
} }
override suspend fun updateProfile(avatar: UploadImage?, nickName: String?, bio: String?) { override suspend fun updateProfile(
avatar: UploadImage?,
banner: UploadImage?,
nickName: String?,
bio: String?
) {
val nicknameField: RequestBody? = nickName?.toRequestBody("text/plain".toMediaTypeOrNull()) val nicknameField: RequestBody? = nickName?.toRequestBody("text/plain".toMediaTypeOrNull())
val bioField: RequestBody? = bio?.toRequestBody("text/plain".toMediaTypeOrNull())
val avatarField: MultipartBody.Part? = avatar?.let { val avatarField: MultipartBody.Part? = avatar?.let {
createMultipartBody(it.file, it.filename, "avatar") createMultipartBody(it.file, it.filename, "avatar")
} }
ApiClient.api.updateProfile(avatarField, nicknameField) val bannerField: MultipartBody.Part? = banner?.let {
createMultipartBody(it.file, it.filename, "banner")
}
ApiClient.api.updateProfile(avatarField, bannerField, nicknameField, bioField)
} }
override suspend fun registerUserWithPassword(loginName: String, password: String) { override suspend fun registerUserWithPassword(loginName: String, password: String) {

View File

@@ -169,7 +169,9 @@ interface RiderProAPI {
@PATCH("account/my/profile") @PATCH("account/my/profile")
suspend fun updateProfile( suspend fun updateProfile(
@Part avatar: MultipartBody.Part?, @Part avatar: MultipartBody.Part?,
@Part banner: MultipartBody.Part?,
@Part("nickname") nickname: RequestBody?, @Part("nickname") nickname: RequestBody?,
@Part("bio") bio: RequestBody?,
): Response<Unit> ): Response<Unit>
@POST("account/my/password") @POST("account/my/password")

View File

@@ -52,7 +52,9 @@ data class AccountProfileEntity(
// 国家 // 国家
val country: String, val country: String,
// 是否关注,针对当前登录用户 // 是否关注,针对当前登录用户
val isFollowing: Boolean val isFollowing: Boolean,
// 主页背景图
val banner: String?,
) )
/** /**

View File

@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
@@ -33,12 +34,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.aiosman.riderpro.entity.AccountProfileEntity import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.data.AccountService import com.aiosman.riderpro.data.AccountService
import com.aiosman.riderpro.data.AccountServiceImpl import com.aiosman.riderpro.data.AccountServiceImpl
import com.aiosman.riderpro.data.UserServiceImpl
import com.aiosman.riderpro.data.UploadImage import com.aiosman.riderpro.data.UploadImage
import com.aiosman.riderpro.data.UserService import com.aiosman.riderpro.entity.AccountProfileEntity
import com.aiosman.riderpro.ui.composables.CustomAsyncImage import com.aiosman.riderpro.ui.composables.CustomAsyncImage
import com.aiosman.riderpro.ui.modifiers.noRippleClickable import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import com.aiosman.riderpro.ui.post.NewPostViewModel.uriToFile import com.aiosman.riderpro.ui.post.NewPostViewModel.uriToFile
@@ -54,11 +54,13 @@ fun AccountEditScreen() {
var name by remember { mutableStateOf("") } var name by remember { mutableStateOf("") }
var bio by remember { mutableStateOf("") } var bio by remember { mutableStateOf("") }
var imageUrl by remember { mutableStateOf<Uri?>(null) } var imageUrl by remember { mutableStateOf<Uri?>(null) }
var bannerImageUrl by remember { mutableStateOf<Uri?>(null) }
var profile by remember { var profile by remember {
mutableStateOf<AccountProfileEntity?>( mutableStateOf<AccountProfileEntity?>(
null null
) )
} }
val navController = LocalNavController.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val context = LocalContext.current val context = LocalContext.current
@@ -71,8 +73,6 @@ fun AccountEditScreen() {
name = it.nickName name = it.nickName
bio = it.bio bio = it.bio
} }
} }
fun updateUserProfile() { fun updateUserProfile() {
@@ -93,10 +93,31 @@ fun AccountEditScreen() {
} }
newAvatar newAvatar
} }
var newBanner = bannerImageUrl?.let {
val cursor = context.contentResolver.query(it, null, null, null, null)
var newBanner: UploadImage? = null
cursor?.use { cur ->
if (cur.moveToFirst()) {
val displayName = cur.getString(cur.getColumnIndex("_display_name"))
val extension = displayName.substringAfterLast(".")
Log.d("NewPost", "File name: $displayName, extension: $extension")
// read as file
val file = uriToFile(context, it)
Log.d("NewPost", "File size: ${file.length()}")
newBanner = UploadImage(file, displayName, it.toString(), extension)
}
}
newBanner
}
val newName = if (name == profile?.nickName) null else name val newName = if (name == profile?.nickName) null else name
accountService.updateProfile(
accountService.updateProfile(newAvatar, newName, bio) avatar = newAvatar,
banner = newBanner,
nickName = newName,
bio = bio
)
reloadProfile() reloadProfile()
navController.popBackStack()
} }
} }
@@ -110,11 +131,20 @@ fun AccountEditScreen() {
} }
} }
} }
val pickBannerImageLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val uri = result.data?.data
uri?.let {
bannerImageUrl = uri
}
}
}
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
reloadProfile() reloadProfile()
} }
Scaffold( Scaffold(
topBar = { topBar = {
TopAppBar( TopAppBar(
@@ -161,6 +191,26 @@ fun AccountEditScreen() {
contentScale = ContentScale.Crop contentScale = ContentScale.Crop
) )
Spacer(modifier = Modifier.size(16.dp)) Spacer(modifier = Modifier.size(16.dp))
CustomAsyncImage(
context,
if (bannerImageUrl != null) {
bannerImageUrl.toString()
} else {
it.banner
},
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.noRippleClickable {
Intent(Intent.ACTION_PICK).apply {
type = "image/*"
pickBannerImageLauncher.launch(this)
}
},
contentScale = ContentScale.Crop
)
Spacer(modifier = Modifier.size(16.dp))
TextField( TextField(
value = name, value = name,
onValueChange = { onValueChange = {

View File

@@ -115,9 +115,10 @@ fun IndexScreen() {
} }
} }
) { innerPadding -> ) { innerPadding ->
innerPadding
HorizontalPager( HorizontalPager(
state = pagerState, state = pagerState,
modifier = Modifier.padding(innerPadding), modifier = Modifier.padding(0.dp),
beyondBoundsPageCount = 5, beyondBoundsPageCount = 5,
userScrollEnabled = false userScrollEnabled = false
) { page -> ) { page ->

View File

@@ -7,11 +7,14 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
@@ -51,6 +54,8 @@ fun NotificationsScreen() {
val systemUiController = rememberSystemUiController() val systemUiController = rememberSystemUiController()
var dataFlow = MessageListViewModel.commentItemsFlow var dataFlow = MessageListViewModel.commentItemsFlow
var comments = dataFlow.collectAsLazyPagingItems() var comments = dataFlow.collectAsLazyPagingItems()
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
systemUiController.setNavigationBarColor(Color.Transparent) systemUiController.setNavigationBarColor(Color.Transparent)
MessageListViewModel.initData() MessageListViewModel.initData()
@@ -59,6 +64,7 @@ fun NotificationsScreen() {
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()
) { ) {
Spacer(modifier = Modifier.padding(statusBarPaddingValues.calculateTopPadding()))
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()

View File

@@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
@@ -21,6 +22,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
@@ -100,44 +102,52 @@ fun MomentsList() {
refreshing = false refreshing = false
} }
} }
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
Box(Modifier.pullRefresh(state)) { Column(
LazyColumn( modifier = Modifier
modifier = Modifier.fillMaxSize(), .fillMaxSize()
) { .padding(
items( top = statusBarPaddingValues.calculateTopPadding(),
moments.itemCount, )
key = { idx -> moments[idx]?.id ?: idx } ) {
) { idx -> Box(Modifier.pullRefresh(state)) {
val momentItem = moments[idx] ?: return@items LazyColumn(
MomentCard(momentEntity = momentItem, modifier = Modifier.fillMaxSize(),
onAddComment = { ) {
scope.launch { items(
model.onAddComment(momentItem.id) moments.itemCount,
} key = { idx -> moments[idx]?.id ?: idx }
}, ) { idx ->
onLikeClick = { val momentItem = moments[idx] ?: return@items
scope.launch { MomentCard(momentEntity = momentItem,
if (momentItem.liked) { onAddComment = {
model.dislikeMoment(momentItem.id) scope.launch {
} else { model.onAddComment(momentItem.id)
model.likeMoment(momentItem.id) }
},
onLikeClick = {
scope.launch {
if (momentItem.liked) {
model.dislikeMoment(momentItem.id)
} else {
model.likeMoment(momentItem.id)
}
}
},
onFavoriteClick = {
scope.launch {
if (momentItem.isFavorite) {
model.unfavoriteMoment(momentItem.id)
} else {
model.favoriteMoment(momentItem.id)
}
} }
} }
}, )
onFavoriteClick = { }
scope.launch {
if (momentItem.isFavorite) {
model.unfavoriteMoment(momentItem.id)
} else {
model.favoriteMoment(momentItem.id)
}
}
}
)
} }
PullRefreshIndicator(refreshing, state, Modifier.align(Alignment.TopCenter))
} }
PullRefreshIndicator(refreshing, state, Modifier.align(Alignment.TopCenter))
} }
} }

View File

@@ -3,7 +3,9 @@ package com.aiosman.riderpro.ui.index.tabs.profile
import android.util.Log import android.util.Log
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.core.Animatable
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@@ -12,12 +14,15 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.LazyListScope
@@ -75,67 +80,92 @@ fun ProfilePage() {
val moments = model.momentsFlow.collectAsLazyPagingItems() val moments = model.momentsFlow.collectAsLazyPagingItems()
val navController: NavController = LocalNavController.current val navController: NavController = LocalNavController.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
LazyColumn( LazyColumn(
modifier = Modifier modifier = Modifier
.fillMaxSize(), .fillMaxSize()
) { ) {
item { item {
Box(
modifier = Modifier
.fillMaxWidth()
) {
val banner = model.profile?.banner
if (banner != null) {
CustomAsyncImage(
LocalContext.current,
banner,
modifier = Modifier
.fillMaxWidth()
.height(400.dp),
contentDescription = "",
contentScale = ContentScale.Crop
)
} else {
Box(
modifier = Modifier
.fillMaxWidth()
.height(400.dp)
.background(Color.Gray)
)
}
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .align(Alignment.TopEnd)
.padding(top = 16.dp, start = 16.dp, end = 16.dp) .padding(
) { top = statusBarPaddingValues.calculateTopPadding(),
Box( start = 16.dp,
modifier = Modifier.align(Alignment.TopEnd) end = 16.dp
) {
Icon(
painter = painterResource(id = R.drawable.rider_pro_more_horizon),
contentDescription = "",
modifier = Modifier.noRippleClickable {
expanded = true
}
) )
DropdownMenu( ) {
expanded = expanded, Icon(
onDismissRequest = { expanded = false } painter = painterResource(id = R.drawable.rider_pro_more_horizon),
) { contentDescription = "",
DropdownMenuItem(onClick = { modifier = Modifier.noRippleClickable {
scope.launch { expanded = true
model.logout() }
navController.navigate(NavigationRoute.Login.route) { )
popUpTo(NavigationRoute.Index.route) { DropdownMenu(
inclusive = true expanded = expanded,
} onDismissRequest = { expanded = false }
) {
DropdownMenuItem(onClick = {
scope.launch {
model.logout()
navController.navigate(NavigationRoute.Login.route) {
popUpTo(NavigationRoute.Index.route) {
inclusive = true
} }
} }
}, text = { }
Text("Logout") }, text = {
}) Text("Logout")
DropdownMenuItem(onClick = { })
scope.launch { DropdownMenuItem(onClick = {
navController.navigate(NavigationRoute.AccountEdit.route) scope.launch {
} navController.navigate(NavigationRoute.AccountEdit.route)
}, text = { }
Text("Edit") }, text = {
}) Text("Edit")
DropdownMenuItem(onClick = { })
scope.launch { DropdownMenuItem(onClick = {
navController.navigate(NavigationRoute.ChangePasswordScreen.route) scope.launch {
} navController.navigate(NavigationRoute.ChangePasswordScreen.route)
}, text = { }
Text("Change password") }, text = {
}) Text("Change password")
} })
} }
} }
CarGroup()
model.profile?.let {
UserInformation(accountProfileEntity = it)
}
// RidingStyle()
} }
// CarGroup()
model.profile?.let {
UserInformation(accountProfileEntity = it)
}
// RidingStyle()
}
items(moments.itemCount) { idx -> items(moments.itemCount) { idx ->
val momentItem = moments[idx] ?: return@items val momentItem = moments[idx] ?: return@items

View File

@@ -6,10 +6,14 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.PagerState
@@ -63,6 +67,8 @@ fun SearchScreen() {
val selectedTabIndex = remember { derivedStateOf { pagerState.currentPage } } val selectedTabIndex = remember { derivedStateOf { pagerState.currentPage } }
val keyboardController = LocalSoftwareKeyboardController.current val keyboardController = LocalSoftwareKeyboardController.current
val systemUiController = rememberSystemUiController() val systemUiController = rememberSystemUiController()
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true) systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true)
} }
@@ -72,6 +78,7 @@ fun SearchScreen() {
.fillMaxSize() .fillMaxSize()
) { ) {
Spacer(modifier = Modifier.height(statusBarPaddingValues.calculateTopPadding()))
SearchInput( SearchInput(
modifier = Modifier.fillMaxWidth().padding(top = 16.dp, start = 24.dp, end = 24.dp), modifier = Modifier.fillMaxWidth().padding(top = 16.dp, start = 24.dp, end = 24.dp),
text = model.searchText, text = model.searchText,