上传
This commit is contained in:
@@ -6,8 +6,6 @@ import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.icu.util.Calendar
|
||||
import android.icu.util.TimeZone
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
@@ -32,12 +30,7 @@ import com.aiosman.riderpro.ui.Navigation
|
||||
import com.aiosman.riderpro.ui.NavigationRoute
|
||||
import com.aiosman.riderpro.ui.navigateToPost
|
||||
import com.aiosman.riderpro.ui.post.NewPostViewModel
|
||||
import com.aiosman.riderpro.utils.Utils
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.tencent.imsdk.v2.V2TIMCallback
|
||||
import com.tencent.imsdk.v2.V2TIMLogListener
|
||||
import com.tencent.imsdk.v2.V2TIMManager
|
||||
import com.tencent.imsdk.v2.V2TIMSDKConfig
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -105,6 +105,9 @@ data class NoticePost(
|
||||
it.copy(
|
||||
url = "${ApiClient.BASE_SERVER}${it.url}",
|
||||
thumbnail = "${ApiClient.BASE_SERVER}${it.thumbnail}",
|
||||
blurHash = it.blurHash,
|
||||
width = it.width,
|
||||
height = it.height
|
||||
)
|
||||
},
|
||||
time = ApiClient.dateFromApiString(time)
|
||||
|
||||
@@ -52,12 +52,14 @@ data class Moment(
|
||||
url = "${ApiClient.BASE_SERVER}${it.url}",
|
||||
thumbnail = "${ApiClient.BASE_SERVER}${it.thumbnail}",
|
||||
id = it.id,
|
||||
blurHash = it.blurHash
|
||||
blurHash = it.blurHash,
|
||||
width = it.width,
|
||||
height = it.height
|
||||
)
|
||||
},
|
||||
authorId = user.id.toInt(),
|
||||
liked = isLiked,
|
||||
isFavorite = isFavorite
|
||||
isFavorite = isFavorite,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -70,7 +72,11 @@ data class Image(
|
||||
@SerializedName("thumbnail")
|
||||
val thumbnail: String,
|
||||
@SerializedName("blurHash")
|
||||
val blurHash: String?
|
||||
val blurHash: String?,
|
||||
@SerializedName("width")
|
||||
val width: Int?,
|
||||
@SerializedName("height")
|
||||
val height: Int?
|
||||
)
|
||||
|
||||
data class User(
|
||||
|
||||
@@ -230,7 +230,11 @@ data class MomentImageEntity(
|
||||
// 缩略图URL
|
||||
val thumbnail: String,
|
||||
// 图片BlurHash
|
||||
val blurHash: String? = null
|
||||
val blurHash: String? = null,
|
||||
// 宽度
|
||||
var width: Int? = null,
|
||||
// 高度
|
||||
var height: Int? = null
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -501,7 +501,6 @@ fun ProfileV3(
|
||||
Spacer(modifier = Modifier.height(120.dp))
|
||||
}
|
||||
}
|
||||
|
||||
1 ->
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
|
||||
@@ -21,15 +21,25 @@ import com.aiosman.riderpro.ui.navigateToPost
|
||||
fun GalleryItem(
|
||||
moment: MomentEntity,
|
||||
idx: Int = 0
|
||||
){
|
||||
) {
|
||||
val navController = LocalNavController.current
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(
|
||||
if (idx % 3 == 0) 1.5f else 1f
|
||||
)
|
||||
.let {
|
||||
val firstImage = moment.images.firstOrNull()
|
||||
if (firstImage?.width != null &&
|
||||
firstImage.height != null &&
|
||||
firstImage.width!! > 0 &&
|
||||
firstImage.height!! > 0
|
||||
) {
|
||||
val ratio = firstImage.width!!.toFloat() / firstImage.height!!.toFloat()
|
||||
return@let it.aspectRatio(ratio.coerceIn(0.7f, 1.5f))
|
||||
} else {
|
||||
return@let it.aspectRatio(if (idx % 3 == 0) 1.5f else 1f)
|
||||
}
|
||||
}
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.noRippleClickable {
|
||||
navController.navigateToPost(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.aiosman.riderpro.ui.index.tabs.search
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -50,7 +49,7 @@ import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
||||
import com.aiosman.riderpro.ui.navigateToPost
|
||||
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
|
||||
@OptIn( ExperimentalMaterialApi::class)
|
||||
@Preview
|
||||
@Composable
|
||||
fun DiscoverScreen() {
|
||||
@@ -82,6 +81,7 @@ fun DiscoverScreen() {
|
||||
.fillMaxWidth()
|
||||
.padding(top = 16.dp, start = 24.dp, end = 24.dp),
|
||||
) {
|
||||
SearchViewModel.requestFocus = true
|
||||
navController.navigate(NavigationRoute.Search.route)
|
||||
}
|
||||
}
|
||||
@@ -150,7 +150,6 @@ fun DiscoverView() {
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1f)
|
||||
.padding(2.dp)
|
||||
|
||||
.noRippleClickable {
|
||||
navController.navigateToPost(
|
||||
id = momentItem.id,
|
||||
|
||||
@@ -4,6 +4,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
@@ -51,9 +52,11 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.aiosman.riderpro.AppState
|
||||
import com.aiosman.riderpro.LocalNavController
|
||||
import com.aiosman.riderpro.R
|
||||
import com.aiosman.riderpro.entity.AccountProfileEntity
|
||||
import com.aiosman.riderpro.ui.composables.ActionButton
|
||||
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
|
||||
import com.aiosman.riderpro.ui.index.tabs.moment.MomentCard
|
||||
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
||||
@@ -82,7 +85,10 @@ fun SearchScreen() {
|
||||
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true)
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequester.requestFocus()
|
||||
if (model.requestFocus) {
|
||||
focusRequester.requestFocus()
|
||||
model.requestFocus = false
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
@@ -246,7 +252,8 @@ fun MomentResultTab() {
|
||||
val momentItem = moments[idx] ?: return@items
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth().background(Color.White)
|
||||
.fillMaxWidth()
|
||||
.background(Color.White)
|
||||
) {
|
||||
MomentCard(momentEntity = momentItem, hideAction = true)
|
||||
}
|
||||
@@ -260,6 +267,7 @@ fun MomentResultTab() {
|
||||
fun UserResultTab() {
|
||||
val model = SearchViewModel
|
||||
val users = model.usersFlow.collectAsLazyPagingItems()
|
||||
val scope = rememberCoroutineScope()
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
@@ -268,14 +276,25 @@ fun UserResultTab() {
|
||||
) {
|
||||
items(users.itemCount) { idx ->
|
||||
val userItem = users[idx] ?: return@items
|
||||
UserItem(userItem)
|
||||
UserItem(userItem) {
|
||||
scope.launch {
|
||||
if (userItem.isFollowing) {
|
||||
model.unfollowUser(userItem.id)
|
||||
} else {
|
||||
model.followUser(userItem.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UserItem(accountProfile: AccountProfileEntity) {
|
||||
fun UserItem(
|
||||
accountProfile: AccountProfileEntity,
|
||||
onFollow: (AccountProfileEntity) -> Unit = {},
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val navController = LocalNavController.current
|
||||
Row(
|
||||
@@ -291,11 +310,52 @@ fun UserItem(accountProfile: AccountProfileEntity) {
|
||||
context,
|
||||
imageUrl = accountProfile.avatar,
|
||||
modifier = Modifier
|
||||
.size(64.dp)
|
||||
.size(48.dp)
|
||||
.clip(CircleShape),
|
||||
contentDescription = null
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(16.dp))
|
||||
Text(text = accountProfile.nickName, fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
||||
Spacer(modifier = Modifier.padding(8.dp))
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Text(text = accountProfile.nickName, fontSize = 16.sp, fontWeight = FontWeight.Bold)
|
||||
Spacer(modifier = Modifier.padding(2.dp))
|
||||
Text(
|
||||
text = stringResource(
|
||||
R.string.search_user_item_follower_count,
|
||||
accountProfile.followerCount
|
||||
), fontSize = 14.sp, color = Color(0xFF9E9E9E)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.padding(8.dp))
|
||||
if (accountProfile.id != AppState.UserId) {
|
||||
if (accountProfile.isFollowing) {
|
||||
ActionButton(
|
||||
text = stringResource(R.string.following_upper),
|
||||
backgroundColor = Color(0xFF9E9E9E),
|
||||
contentPadding = PaddingValues(vertical = 4.dp, horizontal = 8.dp),
|
||||
color = Color.White
|
||||
) {
|
||||
onFollow(accountProfile)
|
||||
}
|
||||
} else {
|
||||
ActionButton(
|
||||
text = stringResource(R.string.follow_upper),
|
||||
backgroundColor = Color(0xffda3832),
|
||||
contentPadding = PaddingValues(vertical = 4.dp, horizontal = 8.dp),
|
||||
color = Color.White
|
||||
) {
|
||||
onFollow(accountProfile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.PagingData
|
||||
import androidx.paging.cachedIn
|
||||
import androidx.paging.map
|
||||
import com.aiosman.riderpro.entity.AccountPagingSource
|
||||
import com.aiosman.riderpro.entity.AccountProfileEntity
|
||||
import com.aiosman.riderpro.entity.MomentPagingSource
|
||||
@@ -17,6 +18,7 @@ import com.aiosman.riderpro.data.MomentService
|
||||
import com.aiosman.riderpro.entity.MomentServiceImpl
|
||||
import com.aiosman.riderpro.data.UserServiceImpl
|
||||
import com.aiosman.riderpro.entity.MomentEntity
|
||||
import com.aiosman.riderpro.ui.index.tabs.moment.MomentViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
@@ -32,7 +34,11 @@ object SearchViewModel : ViewModel() {
|
||||
private val _usersFlow = MutableStateFlow<PagingData<AccountProfileEntity>>(PagingData.empty())
|
||||
val usersFlow = _usersFlow.asStateFlow()
|
||||
var showResult by mutableStateOf(false)
|
||||
var requestFocus by mutableStateOf(false)
|
||||
fun search() {
|
||||
if (searchText.isEmpty()) {
|
||||
return
|
||||
}
|
||||
viewModelScope.launch {
|
||||
Pager(
|
||||
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
|
||||
@@ -62,6 +68,32 @@ object SearchViewModel : ViewModel() {
|
||||
showResult = true
|
||||
}
|
||||
|
||||
suspend fun followUser(id:Int){
|
||||
userService.followUser(id.toString())
|
||||
val currentPagingData = _usersFlow.value
|
||||
val updatedPagingData = currentPagingData.map { userItem ->
|
||||
if (userItem.id == id) {
|
||||
userItem.copy(isFollowing = true, followerCount = userItem.followerCount + 1)
|
||||
} else {
|
||||
userItem
|
||||
}
|
||||
}
|
||||
_usersFlow.value = updatedPagingData
|
||||
}
|
||||
|
||||
suspend fun unfollowUser(id:Int){
|
||||
userService.unFollowUser(id.toString())
|
||||
val currentPagingData = _usersFlow.value
|
||||
val updatedPagingData = currentPagingData.map { userItem ->
|
||||
if (userItem.id == id) {
|
||||
userItem.copy(isFollowing = false, followerCount = userItem.followerCount - 1)
|
||||
} else {
|
||||
userItem
|
||||
}
|
||||
}
|
||||
_usersFlow.value = updatedPagingData
|
||||
}
|
||||
|
||||
fun ResetModel(){
|
||||
_momentsFlow.value = PagingData.empty()
|
||||
_usersFlow.value = PagingData.empty()
|
||||
|
||||
@@ -86,4 +86,5 @@
|
||||
<string name="refresh">刷新</string>
|
||||
<string name="clear">清除</string>
|
||||
<string name="incorrect_captcha_please_try_again">验证码错误,请重试</string>
|
||||
<string name="search_user_item_follower_count">%d 粉丝</string>
|
||||
</resources>
|
||||
@@ -85,4 +85,5 @@
|
||||
<string name="refresh">Refresh</string>
|
||||
<string name="clear">Clear</string>
|
||||
<string name="incorrect_captcha_please_try_again">incorrect captcha,please try again</string>
|
||||
<string name="search_user_item_follower_count">%d followers</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user