更新
This commit is contained in:
@@ -40,6 +40,7 @@ import com.aiosman.riderpro.data.TestAccountServiceImpl
|
|||||||
import com.aiosman.riderpro.data.TestUserServiceImpl
|
import com.aiosman.riderpro.data.TestUserServiceImpl
|
||||||
import com.aiosman.riderpro.data.UploadImage
|
import com.aiosman.riderpro.data.UploadImage
|
||||||
import com.aiosman.riderpro.data.UserService
|
import com.aiosman.riderpro.data.UserService
|
||||||
|
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
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -144,7 +145,8 @@ fun AccountEditScreen() {
|
|||||||
.padding(padding).padding(horizontal = 24.dp),
|
.padding(padding).padding(horizontal = 24.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
if (imageUrl != null) {
|
if (imageUrl != null) {
|
||||||
imageUrl.toString()
|
imageUrl.toString()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.aiosman.riderpro.ui.composables
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import coil.compose.AsyncImage
|
||||||
|
import com.aiosman.riderpro.utils.Utils.getImageLoader
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CustomAsyncImage(
|
||||||
|
context: Context,
|
||||||
|
imageUrl: String,
|
||||||
|
contentDescription: String?,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
contentScale: ContentScale = ContentScale.Crop
|
||||||
|
) {
|
||||||
|
val imageLoader = getImageLoader(context)
|
||||||
|
AsyncImage(
|
||||||
|
model = imageUrl,
|
||||||
|
contentDescription = contentDescription,
|
||||||
|
modifier = modifier,
|
||||||
|
contentScale = contentScale,
|
||||||
|
imageLoader = imageLoader
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.size
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
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.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.aiosman.riderpro.model.MomentEntity
|
import com.aiosman.riderpro.model.MomentEntity
|
||||||
@@ -18,6 +19,7 @@ fun RelPostCard(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val image = momentEntity.images.firstOrNull()
|
val image = momentEntity.images.firstOrNull()
|
||||||
|
val context = LocalContext.current
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
) {
|
) {
|
||||||
@@ -26,7 +28,8 @@ fun RelPostCard(
|
|||||||
modifier=Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
modifier=Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||||
) {
|
) {
|
||||||
image?.let {
|
image?.let {
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
image,
|
image,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.size(100.dp),
|
modifier = Modifier.size(100.dp),
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ import androidx.compose.runtime.LaunchedEffect
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.aiosman.riderpro.LocalAnimatedContentScope
|
import com.aiosman.riderpro.LocalAnimatedContentScope
|
||||||
import com.aiosman.riderpro.LocalNavController
|
import com.aiosman.riderpro.LocalNavController
|
||||||
import com.aiosman.riderpro.LocalSharedTransitionScope
|
import com.aiosman.riderpro.LocalSharedTransitionScope
|
||||||
|
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
|
||||||
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
|
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
|
||||||
import com.aiosman.riderpro.ui.imageviewer.ImageViewerViewModel
|
import com.aiosman.riderpro.ui.imageviewer.ImageViewerViewModel
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
@@ -31,7 +33,7 @@ fun ImageViewer() {
|
|||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
val sharedTransitionScope = LocalSharedTransitionScope.current
|
val sharedTransitionScope = LocalSharedTransitionScope.current
|
||||||
val animatedVisibilityScope = LocalAnimatedContentScope.current
|
val animatedVisibilityScope = LocalAnimatedContentScope.current
|
||||||
|
val context = LocalContext.current
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
systemUiController.setStatusBarColor(Color.Black)
|
systemUiController.setStatusBarColor(Color.Black)
|
||||||
systemUiController.setNavigationBarColor(Color.Black)
|
systemUiController.setNavigationBarColor(Color.Black)
|
||||||
@@ -50,7 +52,8 @@ fun ImageViewer() {
|
|||||||
) { page ->
|
) { page ->
|
||||||
val zoomState = rememberZoomState()
|
val zoomState = rememberZoomState()
|
||||||
with(sharedTransitionScope) {
|
with(sharedTransitionScope) {
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
images[page],
|
images[page],
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.sharedElement(
|
modifier = Modifier.sharedElement(
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
@@ -63,6 +64,7 @@ import com.aiosman.riderpro.ui.comment.CommentModalContent
|
|||||||
import com.aiosman.riderpro.ui.composables.AnimatedCounter
|
import com.aiosman.riderpro.ui.composables.AnimatedCounter
|
||||||
import com.aiosman.riderpro.ui.composables.AnimatedFavouriteIcon
|
import com.aiosman.riderpro.ui.composables.AnimatedFavouriteIcon
|
||||||
import com.aiosman.riderpro.ui.composables.AnimatedLikeIcon
|
import com.aiosman.riderpro.ui.composables.AnimatedLikeIcon
|
||||||
|
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
|
||||||
import com.aiosman.riderpro.ui.composables.RelPostCard
|
import com.aiosman.riderpro.ui.composables.RelPostCard
|
||||||
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
||||||
import com.aiosman.riderpro.ui.post.NewPostViewModel
|
import com.aiosman.riderpro.ui.post.NewPostViewModel
|
||||||
@@ -265,12 +267,14 @@ fun MomentPostTime(time: String) {
|
|||||||
@Composable
|
@Composable
|
||||||
fun MomentTopRowGroup(momentEntity: MomentEntity) {
|
fun MomentTopRowGroup(momentEntity: MomentEntity) {
|
||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
|
val context = LocalContext.current
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.height(40.dp)
|
.height(40.dp)
|
||||||
.padding(top = 0.dp, bottom = 0.dp, start = 24.dp, end = 24.dp)
|
.padding(top = 0.dp, bottom = 0.dp, start = 24.dp, end = 24.dp)
|
||||||
) {
|
) {
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
momentEntity.avatar,
|
momentEntity.avatar,
|
||||||
contentDescription = "",
|
contentDescription = "",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -320,6 +324,7 @@ fun MomentContentGroup(
|
|||||||
val displayImageUrl = momentEntity.images.firstOrNull()
|
val displayImageUrl = momentEntity.images.firstOrNull()
|
||||||
val sharedTransitionScope = LocalSharedTransitionScope.current
|
val sharedTransitionScope = LocalSharedTransitionScope.current
|
||||||
val animatedVisibilityScope = LocalAnimatedContentScope.current
|
val animatedVisibilityScope = LocalAnimatedContentScope.current
|
||||||
|
val context = LocalContext.current
|
||||||
Text(
|
Text(
|
||||||
text = "${momentEntity.momentTextContent}",
|
text = "${momentEntity.momentTextContent}",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -335,7 +340,8 @@ fun MomentContentGroup(
|
|||||||
} else {
|
} else {
|
||||||
displayImageUrl?.let {
|
displayImageUrl?.let {
|
||||||
with(sharedTransitionScope) {
|
with(sharedTransitionScope) {
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
it,
|
it,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.sharedElement(
|
.sharedElement(
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import androidx.compose.ui.draw.clip
|
|||||||
import androidx.compose.ui.draw.shadow
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
@@ -54,6 +55,7 @@ import com.aiosman.riderpro.R
|
|||||||
import com.aiosman.riderpro.data.AccountProfileEntity
|
import com.aiosman.riderpro.data.AccountProfileEntity
|
||||||
import com.aiosman.riderpro.model.MomentEntity
|
import com.aiosman.riderpro.model.MomentEntity
|
||||||
import com.aiosman.riderpro.ui.NavigationRoute
|
import com.aiosman.riderpro.ui.NavigationRoute
|
||||||
|
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
|
||||||
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -246,6 +248,7 @@ fun UserInformationFollowers(modifier: Modifier, accountProfileEntity: AccountPr
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserInformationBasic(modifier: Modifier, accountProfileEntity: AccountProfileEntity) {
|
fun UserInformationBasic(modifier: Modifier, accountProfileEntity: AccountProfileEntity) {
|
||||||
|
val context = LocalContext.current
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
@@ -257,7 +260,8 @@ fun UserInformationBasic(modifier: Modifier, accountProfileEntity: AccountProfil
|
|||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
painter = painterResource(id = R.drawable.avatar_bold), contentDescription = ""
|
painter = painterResource(id = R.drawable.avatar_bold), contentDescription = ""
|
||||||
)
|
)
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
accountProfileEntity.avatar,
|
accountProfileEntity.avatar,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(width = 88.dp, height = 88.dp)
|
.size(width = 88.dp, height = 88.dp)
|
||||||
@@ -571,8 +575,10 @@ fun MomentCardPicture(imageUrl: String, momentId: Int) {
|
|||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
val sharedTransitionScope = LocalSharedTransitionScope.current
|
val sharedTransitionScope = LocalSharedTransitionScope.current
|
||||||
val animatedVisibilityScope = LocalAnimatedContentScope.current
|
val animatedVisibilityScope = LocalAnimatedContentScope.current
|
||||||
|
val context = LocalContext.current
|
||||||
with(sharedTransitionScope) {
|
with(sharedTransitionScope) {
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
imageUrl,
|
imageUrl,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.sharedElement(
|
.sharedElement(
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.aiosman.riderpro.LocalNavController
|
import com.aiosman.riderpro.LocalNavController
|
||||||
import com.aiosman.riderpro.R
|
import com.aiosman.riderpro.R
|
||||||
|
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
|
||||||
import com.aiosman.riderpro.ui.composables.RelPostCard
|
import com.aiosman.riderpro.ui.composables.RelPostCard
|
||||||
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
|
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
|
||||||
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
||||||
@@ -199,7 +200,8 @@ fun AddImageGrid() {
|
|||||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
) {
|
) {
|
||||||
model.imageUriList.forEach {
|
model.imageUriList.forEach {
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
it,
|
it,
|
||||||
contentDescription = "Image",
|
contentDescription = "Image",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
@@ -90,6 +91,7 @@ import com.aiosman.riderpro.model.MomentEntity
|
|||||||
import com.aiosman.riderpro.ui.NavigationRoute
|
import com.aiosman.riderpro.ui.NavigationRoute
|
||||||
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
|
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
|
||||||
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
|
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
|
||||||
|
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
|
||||||
import com.aiosman.riderpro.ui.composables.EditCommentBottomModal
|
import com.aiosman.riderpro.ui.composables.EditCommentBottomModal
|
||||||
import com.aiosman.riderpro.ui.imageviewer.ImageViewerViewModel
|
import com.aiosman.riderpro.ui.imageviewer.ImageViewerViewModel
|
||||||
import com.aiosman.riderpro.ui.index.tabs.moment.MomentViewModel
|
import com.aiosman.riderpro.ui.index.tabs.moment.MomentViewModel
|
||||||
@@ -353,6 +355,7 @@ fun Header(
|
|||||||
onFollowClick: () -> Unit
|
onFollowClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
|
val context = LocalContext.current
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -370,7 +373,8 @@ fun Header(
|
|||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
avatar?.let {
|
avatar?.let {
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
it,
|
it,
|
||||||
contentDescription = "Profile Picture",
|
contentDescription = "Profile Picture",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -428,6 +432,8 @@ fun PostImageView(
|
|||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
val sharedTransitionScope = LocalSharedTransitionScope.current
|
val sharedTransitionScope = LocalSharedTransitionScope.current
|
||||||
val animatedVisibilityScope = LocalAnimatedContentScope.current
|
val animatedVisibilityScope = LocalAnimatedContentScope.current
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
@@ -437,7 +443,8 @@ fun PostImageView(
|
|||||||
) { page ->
|
) { page ->
|
||||||
val image = images[page]
|
val image = images[page]
|
||||||
with(sharedTransitionScope) {
|
with(sharedTransitionScope) {
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
image,
|
image,
|
||||||
contentDescription = "Image",
|
contentDescription = "Image",
|
||||||
contentScale = ContentScale.Fit,
|
contentScale = ContentScale.Fit,
|
||||||
@@ -547,9 +554,11 @@ fun CommentsSection(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CommentItem(commentEntity: CommentEntity, onLike: () -> Unit = {}) {
|
fun CommentItem(commentEntity: CommentEntity, onLike: () -> Unit = {}) {
|
||||||
|
val context = LocalContext.current
|
||||||
Column {
|
Column {
|
||||||
Row(modifier = Modifier.padding(vertical = 8.dp)) {
|
Row(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||||
AsyncImage(
|
CustomAsyncImage(
|
||||||
|
context,
|
||||||
commentEntity.avatar,
|
commentEntity.avatar,
|
||||||
contentDescription = "Comment Profile Picture",
|
contentDescription = "Comment Profile Picture",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
package com.aiosman.riderpro.utils
|
package com.aiosman.riderpro.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import coil.ImageLoader
|
||||||
|
import coil.request.CachePolicy
|
||||||
|
import com.aiosman.riderpro.data.api.getUnsafeOkHttpClient
|
||||||
|
|
||||||
object Utils {
|
object Utils {
|
||||||
fun generateRandomString(length: Int): String {
|
fun generateRandomString(length: Int): String {
|
||||||
val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
|
val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
|
||||||
@@ -7,4 +12,15 @@ object Utils {
|
|||||||
.map { allowedChars.random() }
|
.map { allowedChars.random() }
|
||||||
.joinToString("")
|
.joinToString("")
|
||||||
}
|
}
|
||||||
|
fun getImageLoader(context: Context): ImageLoader {
|
||||||
|
val okHttpClient = getUnsafeOkHttpClient()
|
||||||
|
return ImageLoader.Builder(context)
|
||||||
|
.okHttpClient(okHttpClient)
|
||||||
|
.diskCachePolicy(CachePolicy.ENABLED)
|
||||||
|
.memoryCachePolicy(CachePolicy.ENABLED)
|
||||||
|
.components {
|
||||||
|
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user