This commit is contained in:
2024-07-31 14:50:55 +08:00
parent 2c79195f44
commit b17ac76005
63 changed files with 344 additions and 42 deletions

View File

@@ -31,6 +31,8 @@ import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.currentBackStackEntryAsState
import com.aiosman.riderpro.data.AccountService
import com.aiosman.riderpro.data.TestAccountServiceImpl
import com.aiosman.riderpro.data.TestUserServiceImpl import com.aiosman.riderpro.data.TestUserServiceImpl
import com.aiosman.riderpro.data.UserService import com.aiosman.riderpro.data.UserService
import com.aiosman.riderpro.ui.Navigation import com.aiosman.riderpro.ui.Navigation
@@ -49,8 +51,8 @@ class MainActivity : ComponentActivity() {
if (!AppStore.rememberMe) { if (!AppStore.rememberMe) {
return return
} }
val userService: UserService = TestUserServiceImpl() val accountService: AccountService = TestAccountServiceImpl()
userService.getMyAccount() accountService.getMyAccount()
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@@ -15,14 +15,50 @@ data class AccountProfile(
interface AccountService { interface AccountService {
suspend fun getMyAccountProfile(): AccountProfile suspend fun getMyAccountProfile(): AccountProfile
suspend fun getAccountProfileById(id: Int): AccountProfile suspend fun getAccountProfileById(id: Int): AccountProfile
suspend fun getMyAccount(): UserAuth
suspend fun loginUserWithPassword(loginName: String, password: String): UserAuth
suspend fun logout()
suspend fun updateAvatar(uri: String)
suspend fun updateProfile(nickName: String, bio: String)
} }
class TestAccountServiceImpl : AccountService { class TestAccountServiceImpl : AccountService {
override suspend fun getMyAccountProfile(): AccountProfile { override suspend fun getMyAccountProfile(): AccountProfile {
return TestDatabase.accountData.first { it.id == 0 } return TestDatabase.accountData.first { it.id == 1 }
} }
override suspend fun getAccountProfileById(id: Int): AccountProfile { override suspend fun getAccountProfileById(id: Int): AccountProfile {
return TestDatabase.accountData.first { it.id == id } return TestDatabase.accountData.first { it.id == id }
} }
override suspend fun getMyAccount(): UserAuth {
return UserAuth(1)
}
override suspend fun loginUserWithPassword(loginName: String, password: String): UserAuth {
return UserAuth(1, "token")
}
override suspend fun logout() {
// do nothing
}
override suspend fun updateAvatar(uri: String) {
TestDatabase.accountData = TestDatabase.accountData.map {
if (it.id == 1) {
it.copy(avatar = uri)
} else {
it
}
}
}
override suspend fun updateProfile(nickName: String, bio: String) {
TestDatabase.accountData = TestDatabase.accountData.map {
if (it.id == 1) {
it.copy(nickName = nickName, bio = bio)
} else {
it
}
}
}
} }

View File

@@ -21,7 +21,8 @@ interface MomentService {
suspend fun createMoment( suspend fun createMoment(
content: String, content: String,
authorId: Int, authorId: Int,
imageUriList: List<String> imageUriList: List<String>,
relPostId: Int? = null
): MomentItem ): MomentItem
} }
@@ -96,9 +97,10 @@ class TestMomentServiceImpl() : MomentService {
override suspend fun createMoment( override suspend fun createMoment(
content: String, content: String,
authorId: Int, authorId: Int,
imageUriList: List<String> imageUriList: List<String>,
relPostId: Int?
): MomentItem { ): MomentItem {
return testMomentBackend.createMoment(content, authorId, imageUriList) return testMomentBackend.createMoment(content, authorId, imageUriList, relPostId)
} }
} }
@@ -140,6 +142,9 @@ class TestMomentBackend(
if (myLikeIdList.contains(it.id)) { if (myLikeIdList.contains(it.id)) {
it.liked = true it.liked = true
} }
if (it.relPostId != null) {
it.relMoment = rawList.first { it1 -> it1.id == it.relPostId }
}
} }
// delay // delay
@@ -186,7 +191,8 @@ class TestMomentBackend(
suspend fun createMoment( suspend fun createMoment(
content: String, content: String,
authorId: Int, authorId: Int,
imageUriList: List<String> imageUriList: List<String>,
relPostId: Int?
): MomentItem { ): MomentItem {
TestDatabase.momentIdCounter += 1 TestDatabase.momentIdCounter += 1
val person = TestDatabase.accountData.first { val person = TestDatabase.accountData.first {
@@ -206,7 +212,8 @@ class TestMomentBackend(
shareCount = 0, shareCount = 0,
favoriteCount = 0, favoriteCount = 0,
images = imageUriList, images = imageUriList,
authorId = person.id authorId = person.id,
relPostId = relPostId
) )
TestDatabase.momentData += newMoment TestDatabase.momentData += newMoment
return newMoment return newMoment

View File

@@ -9,9 +9,7 @@ data class UserAuth(
interface UserService { interface UserService {
suspend fun getUserProfile(id: String): AccountProfile suspend fun getUserProfile(id: String): AccountProfile
suspend fun getMyAccount(): UserAuth
suspend fun loginUserWithPassword(loginName: String, password: String): UserAuth
suspend fun logout()
} }
class TestUserServiceImpl : UserService { class TestUserServiceImpl : UserService {
@@ -23,17 +21,4 @@ class TestUserServiceImpl : UserService {
} }
return AccountProfile(0, 0, 0, "", "", "", "") return AccountProfile(0, 0, 0, "", "", "", "")
} }
override suspend fun getMyAccount(): UserAuth {
return UserAuth(1)
}
override suspend fun loginUserWithPassword(loginName: String, password: String): UserAuth {
return UserAuth(1, "token")
}
override suspend fun logout() {
// do nothing
}
} }

View File

@@ -19,4 +19,6 @@ data class MomentItem(
val images: List<String> = emptyList(), val images: List<String> = emptyList(),
val authorId: Int = 0, val authorId: Int = 0,
var liked: Boolean = false, var liked: Boolean = false,
var relPostId: Int? = null,
var relMoment: MomentItem? = null
) )

View File

@@ -21,6 +21,7 @@ import androidx.navigation.navArgument
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.account.AccountEditScreen
import com.aiosman.riderpro.ui.comment.CommentsScreen import com.aiosman.riderpro.ui.comment.CommentsScreen
import com.aiosman.riderpro.ui.follower.FollowerScreen import com.aiosman.riderpro.ui.follower.FollowerScreen
import com.aiosman.riderpro.ui.gallery.OfficialGalleryScreen import com.aiosman.riderpro.ui.gallery.OfficialGalleryScreen
@@ -60,11 +61,15 @@ sealed class NavigationRoute(
data object SignUp : NavigationRoute("SignUp") data object SignUp : NavigationRoute("SignUp")
data object UserAuth : NavigationRoute("UserAuth") data object UserAuth : NavigationRoute("UserAuth")
data object EmailSignUp : NavigationRoute("EmailSignUp") data object EmailSignUp : NavigationRoute("EmailSignUp")
data object AccountEdit : NavigationRoute("AccountEditScreen")
} }
@Composable @Composable
fun NavigationController(navController: NavHostController,startDestination: String = NavigationRoute.Login.route) { fun NavigationController(
navController: NavHostController,
startDestination: String = NavigationRoute.Login.route
) {
val navigationBarHeight = with(LocalDensity.current) { val navigationBarHeight = with(LocalDensity.current) {
WindowInsets.navigationBars.getBottom(this).toDp() WindowInsets.navigationBars.getBottom(this).toDp()
} }
@@ -163,6 +168,9 @@ fun NavigationController(navController: NavHostController,startDestination: Stri
composable(route = NavigationRoute.EmailSignUp.route) { composable(route = NavigationRoute.EmailSignUp.route) {
EmailSignupScreen() EmailSignupScreen()
} }
composable(route = NavigationRoute.AccountEdit.route) {
AccountEditScreen()
}
} }
@@ -178,7 +186,10 @@ fun Navigation(startDestination: String = NavigationRoute.Login.route) {
LocalSharedTransitionScope provides this@SharedTransitionLayout, LocalSharedTransitionScope provides this@SharedTransitionLayout,
) { ) {
Box { Box {
NavigationController(navController = navController,startDestination = startDestination) NavigationController(
navController = navController,
startDestination = startDestination
)
} }
} }
} }

View File

@@ -0,0 +1,166 @@
package com.aiosman.riderpro.ui.account
import android.app.Activity
import android.content.Intent
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import com.aiosman.riderpro.data.AccountProfile
import com.aiosman.riderpro.data.AccountService
import com.aiosman.riderpro.data.TestAccountServiceImpl
import com.aiosman.riderpro.data.TestUserServiceImpl
import com.aiosman.riderpro.data.UserService
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AccountEditScreen() {
val userService: UserService = TestUserServiceImpl()
val accountService: AccountService = TestAccountServiceImpl()
var name by remember { mutableStateOf("") }
var bio by remember { mutableStateOf("") }
var profile by remember {
mutableStateOf<AccountProfile?>(
null
)
}
val scope = rememberCoroutineScope()
suspend fun reloadProfile() {
accountService.getMyAccountProfile().let {
profile = it
name = it.nickName
bio = it.bio
}
}
fun updateUserAvatar(uri: String) {
scope.launch {
accountService.updateAvatar(uri)
reloadProfile()
}
}
fun updateUserProfile() {
scope.launch {
accountService.updateProfile(name, bio)
reloadProfile()
}
}
val pickImageLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val uri = result.data?.data
uri?.let {
updateUserAvatar(it.toString())
}
}
}
LaunchedEffect(Unit) {
reloadProfile()
}
Scaffold(
topBar = {
TopAppBar(
title = { Text("Edit") },
)
},
floatingActionButton = {
FloatingActionButton(
onClick = {
updateUserProfile()
}
) {
Icon(
imageVector = Icons.Default.Check,
contentDescription = "Save"
)
}
}
) {
padding ->
profile?.let {
Column(
modifier = Modifier
.fillMaxSize()
.padding(padding).padding(horizontal = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
AsyncImage(
it.avatar,
contentDescription = null,
modifier = Modifier
.size(100.dp)
.noRippleClickable {
Intent(Intent.ACTION_PICK).apply {
type = "image/*"
pickImageLauncher.launch(this)
}
},
contentScale = ContentScale.Crop
)
Spacer(modifier = Modifier.size(16.dp))
TextField(
value = name,
onValueChange = {
name = it
},
label = {
Text("Name")
},
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.size(16.dp))
TextField(
value = bio,
onValueChange = {
bio = it
},
label = {
Text("Bio")
},
modifier = Modifier.fillMaxWidth()
)
}
}
}
}

View File

@@ -0,0 +1,38 @@
package com.aiosman.riderpro.ui.composables
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import com.aiosman.riderpro.model.MomentItem
import com.aiosman.riderpro.ui.index.tabs.moment.MomentTopRowGroup
@Composable
fun RelPostCard(
momentItem: MomentItem,
modifier: Modifier = Modifier,
) {
val image = momentItem.images.firstOrNull()
Column(
modifier = modifier
) {
MomentTopRowGroup(momentItem = momentItem)
Box(
modifier=Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
) {
image?.let {
AsyncImage(
image,
contentDescription = null,
modifier = Modifier.size(100.dp),
contentScale = ContentScale.Crop
)
}
}
}
}

View File

@@ -60,7 +60,9 @@ import com.aiosman.riderpro.ui.NavigationRoute
import com.aiosman.riderpro.ui.comment.CommentModalContent 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.AnimatedLikeIcon import com.aiosman.riderpro.ui.composables.AnimatedLikeIcon
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.google.accompanist.systemuicontroller.rememberSystemUiController import com.google.accompanist.systemuicontroller.rememberSystemUiController
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -68,7 +70,6 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterialApi::class) @OptIn(ExperimentalMaterialApi::class)
@Composable @Composable
fun MomentsList() { fun MomentsList() {
val model = MomentViewModel val model = MomentViewModel
var dataFlow = model.momentsFlow var dataFlow = model.momentsFlow
var moments = dataFlow.collectAsLazyPagingItems() var moments = dataFlow.collectAsLazyPagingItems()
@@ -110,7 +111,6 @@ fun MomentsList() {
} }
PullRefreshIndicator(refreshing, state, Modifier.align(Alignment.TopCenter)) PullRefreshIndicator(refreshing, state, Modifier.align(Alignment.TopCenter))
} }
} }
@Composable @Composable
@@ -141,7 +141,12 @@ fun MomentCard(
momentOperateBtnBoxModifier, momentOperateBtnBoxModifier,
momentItem = momentItem, momentItem = momentItem,
onLikeClick = onLikeClick, onLikeClick = onLikeClick,
onAddComment = onAddComment onAddComment = onAddComment,
onShareClick = {
NewPostViewModel.asNewPost()
NewPostViewModel.relPostId = momentItem.id
navController.navigate(NavigationRoute.NewPost.route)
}
) )
} }
} }
@@ -305,6 +310,9 @@ fun MomentContentGroup(
.padding(top = 22.dp, bottom = 16.dp, start = 24.dp, end = 24.dp), .padding(top = 22.dp, bottom = 16.dp, start = 24.dp, end = 24.dp),
fontSize = 16.sp fontSize = 16.sp
) )
if (momentItem.relMoment != null) {
RelPostCard(momentItem = momentItem.relMoment!!, modifier = Modifier.background(Color(0xFFF8F8F8)))
}else{
displayImageUrl?.let { displayImageUrl?.let {
AsyncImage( AsyncImage(
it, it,
@@ -315,6 +323,7 @@ fun MomentContentGroup(
contentDescription = "" contentDescription = ""
) )
} }
}
} }
@@ -357,6 +366,7 @@ fun MomentBottomOperateRowGroup(
modifier: Modifier, modifier: Modifier,
onLikeClick: () -> Unit = {}, onLikeClick: () -> Unit = {},
onAddComment: () -> Unit = {}, onAddComment: () -> Unit = {},
onShareClick: () -> Unit = {},
momentItem: MomentItem momentItem: MomentItem
) { ) {
var systemUiController = rememberSystemUiController() var systemUiController = rememberSystemUiController()
@@ -411,7 +421,9 @@ fun MomentBottomOperateRowGroup(
) )
} }
Box( Box(
modifier = modifier, modifier = modifier.noRippleClickable {
onShareClick()
},
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
MomentOperateBtn( MomentOperateBtn(

View File

@@ -106,6 +106,13 @@ fun ProfilePage() {
}, text = { }, text = {
Text("Logout") Text("Logout")
}) })
DropdownMenuItem(onClick = {
scope.launch {
navController.navigate(NavigationRoute.AccountEdit.route)
}
}, text = {
Text("Edit")
})
} }
} }

View File

@@ -37,6 +37,8 @@ import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.AppStore import com.aiosman.riderpro.AppStore
import com.aiosman.riderpro.LocalNavController import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.R import com.aiosman.riderpro.R
import com.aiosman.riderpro.data.AccountService
import com.aiosman.riderpro.data.TestAccountServiceImpl
import com.aiosman.riderpro.data.TestUserServiceImpl import com.aiosman.riderpro.data.TestUserServiceImpl
import com.aiosman.riderpro.data.UserService import com.aiosman.riderpro.data.UserService
import com.aiosman.riderpro.ui.NavigationRoute import com.aiosman.riderpro.ui.NavigationRoute
@@ -52,12 +54,12 @@ fun UserAuthScreen() {
var email by remember { mutableStateOf("") } var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") } var password by remember { mutableStateOf("") }
var rememberMe by remember { mutableStateOf(false) } var rememberMe by remember { mutableStateOf(false) }
var userService: UserService = TestUserServiceImpl() var accountService: AccountService = TestAccountServiceImpl()
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val navController = LocalNavController.current val navController = LocalNavController.current
fun onLogin() { fun onLogin() {
scope.launch { scope.launch {
val authResp = userService.loginUserWithPassword(email, password) val authResp = accountService.loginUserWithPassword(email, password)
if (authResp.token != null) { if (authResp.token != null) {
AppStore.apply { AppStore.apply {
token = authResp.token token = authResp.token

View File

@@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.heightIn
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.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.ModalBottomSheet
@@ -34,6 +35,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathEffect import androidx.compose.ui.graphics.PathEffect
@@ -48,6 +50,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.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
import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.google.accompanist.systemuicontroller.rememberSystemUiController
@@ -62,6 +65,7 @@ fun NewPostScreen() {
val navController = LocalNavController.current val navController = LocalNavController.current
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
systemUiController.setNavigationBarColor(color = Color.Transparent) systemUiController.setNavigationBarColor(color = Color.Transparent)
model.init()
} }
StatusBarMaskLayout( StatusBarMaskLayout(
darkIcons = true, darkIcons = true,
@@ -79,6 +83,23 @@ fun NewPostScreen() {
NewPostTextField("Share your adventure…", NewPostViewModel.textContent) { NewPostTextField("Share your adventure…", NewPostViewModel.textContent) {
NewPostViewModel.textContent = it NewPostViewModel.textContent = it
} }
Column (
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp)
) {
model.relMoment?.let {
Text("Share with")
Spacer(modifier = Modifier.height(8.dp))
Box(
modifier = Modifier.clip(RoundedCornerShape(8.dp)).background(color = Color(0xFFEEEEEE)).padding(24.dp)
) {
RelPostCard(
momentItem = it,
modifier = Modifier.fillMaxWidth()
)
}
}
}
AddImageGrid() AddImageGrid()
AdditionalPostItem() AdditionalPostItem()
} }

View File

@@ -8,6 +8,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.aiosman.riderpro.data.MomentService import com.aiosman.riderpro.data.MomentService
import com.aiosman.riderpro.data.TestMomentServiceImpl import com.aiosman.riderpro.data.TestMomentServiceImpl
import com.aiosman.riderpro.model.MomentItem
import com.aiosman.riderpro.ui.modification.Modification import com.aiosman.riderpro.ui.modification.Modification
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -18,17 +19,29 @@ object NewPostViewModel : ViewModel() {
var searchPlaceAddressResult by mutableStateOf<SearchPlaceAddressResult?>(null) var searchPlaceAddressResult by mutableStateOf<SearchPlaceAddressResult?>(null)
var modificationList by mutableStateOf<List<Modification>>(listOf()) var modificationList by mutableStateOf<List<Modification>>(listOf())
var imageUriList by mutableStateOf(listOf<String>()) var imageUriList by mutableStateOf(listOf<String>())
var relPostId by mutableStateOf<Int?>(null)
var relMoment by mutableStateOf<MomentItem?>(null)
fun asNewPost() { fun asNewPost() {
textContent = "" textContent = ""
searchPlaceAddressResult = null searchPlaceAddressResult = null
modificationList = listOf() modificationList = listOf()
imageUriList = listOf()
relPostId = null
} }
suspend fun createMoment() { suspend fun createMoment() {
momentService.createMoment( momentService.createMoment(
content = textContent, content = textContent,
authorId = 1, authorId = 1,
imageUriList = imageUriList imageUriList = imageUriList,
relPostId = relPostId
) )
} }
suspend fun init(){
relPostId?.let {
val moment = momentService.getMomentById(it)
relMoment = moment
}
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 956 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB