diff --git a/app/src/main/java/com/d_vide/D_VIDE/app/domain/model/Message.kt b/app/src/main/java/com/d_vide/D_VIDE/app/domain/model/Message.kt index 5d47ac9d..c9e4bcb7 100644 --- a/app/src/main/java/com/d_vide/D_VIDE/app/domain/model/Message.kt +++ b/app/src/main/java/com/d_vide/D_VIDE/app/domain/model/Message.kt @@ -5,9 +5,9 @@ import androidx.compose.runtime.mutableStateListOf import com.d_vide.D_VIDE.R data class ConversationUiState( - var channelName: String = "채팅방 이름", + var channelName: String = "", val chatId: String = "", - val messages: MutableList = mutableListOf(), + var messages: MutableList = mutableListOf(), var users: MutableMap = HashMap() ) diff --git a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/navigation/NavGraph.kt b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/navigation/NavGraph.kt index f982b8a3..f9d07b2a 100644 --- a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/navigation/NavGraph.kt +++ b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/navigation/NavGraph.kt @@ -81,7 +81,12 @@ fun NavGraphBuilder.divideGraph( ) { backStackEntry -> val arguments = requireNotNull(backStackEntry.arguments) val chattingId = arguments.getInt(DetailDestinationKey.CHATTING) - ChattingDetail(chattingId = chattingId, upPress = upPress) + ChattingDetail( + navController, + onReviewSelected = { id -> onReviewClick(id, backStackEntry) }, + onTagClick = { id -> onTagClick(id, backStackEntry) }, + chattingId = chattingId, + upPress = upPress) } composable( diff --git a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/ChattingDetail.kt b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/ChattingDetail.kt index 67c8a531..aa3f745b 100644 --- a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/ChattingDetail.kt +++ b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/ChattingDetail.kt @@ -1,46 +1,96 @@ package com.d_vide.D_VIDE.app.presentation.ChattingDetail +import androidx.activity.compose.BackHandler +import androidx.compose.animation.core.tween import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController import com.d_vide.D_VIDE.R +import com.d_vide.D_VIDE.app._constants.Const import com.d_vide.D_VIDE.app.domain.model.ConversationUiState import com.d_vide.D_VIDE.app.domain.model.Message import com.d_vide.D_VIDE.app.presentation.ChattingDetail.component.UserInput +import com.d_vide.D_VIDE.app.presentation.Reviews.RecommendRow +import com.d_vide.D_VIDE.app.presentation.navigation.Screen +import com.d_vide.D_VIDE.app.presentation.util.GradientComponent import com.d_vide.D_VIDE.app.presentation.view.ChattingDetail.ChattingDetailViewModel import com.d_vide.D_VIDE.app.presentation.view.ChattingDetail.component.Messages +import com.d_vide.D_VIDE.app.presentation.view.TaggedReviews.component.ReviewItem +import com.d_vide.D_VIDE.app.presentation.view.UserFeed.BottomSheetUserFeedScreen +import com.d_vide.D_VIDE.app.presentation.view.UserFeed.UserFeedViewModel +import com.d_vide.D_VIDE.app.presentation.view.component.RecruitingWriteButton import com.d_vide.D_VIDE.app.presentation.view.component.TopBarChatting +import com.d_vide.D_VIDE.app.presentation.view.component.TopRoundBarWithImage +import com.d_vide.D_VIDE.ui.theme.gray6 import kotlinx.coroutines.launch +@OptIn(ExperimentalMaterialApi::class) @Composable fun ChattingDetail( + navController: NavController, + onReviewSelected: (Int) -> Unit, + onTagClick: (String) -> Unit, chattingId: Int, upPress: () -> Unit = {}, - viewModel: ChattingDetailViewModel = hiltViewModel() + viewModel: ChattingDetailViewModel = hiltViewModel(), + userFeedViewModel: UserFeedViewModel = hiltViewModel(), ) { - ConversationContent( - uiState = viewModel.state.value, - navigateToProfile = { user -> - }, - // Add padding so that we are inset from any navigation bars - modifier = Modifier.windowInsetsPadding( - WindowInsets - .navigationBars - .only(WindowInsetsSides.Horizontal + WindowInsetsSides.Top) - ), - onMessageSent = { content -> - viewModel.send(Message("authorMe", content, System.currentTimeMillis())) - }, - upPress = upPress - ) + val userId = rememberSaveable{ mutableStateOf(0L) } + + + BottomSheetUserFeedScreen( + navController = navController, + onReviewSelected = onReviewSelected, + onTagClick = onTagClick, + userId = userId.value + ) { state, scope -> + ConversationContent( + navigateToProfile = { + userId.value = it.toLong() + scope.launch { + userFeedViewModel.getOtherUserInfo(it.toLong()) + state.animateTo(ModalBottomSheetValue.Expanded, tween(500)) + } + }, + uiState = viewModel.state, + // Add padding so that we are inset from any navigation bars + modifier = Modifier.windowInsetsPadding( + WindowInsets + .navigationBars + .only(WindowInsetsSides.Horizontal + WindowInsetsSides.Top) + ), + onMessageSent = { content -> + viewModel.send(content) + }, + upPress = upPress + ) + BackHandler ( + enabled = (state.currentValue == ModalBottomSheetValue.HalfExpanded || + state.currentValue == ModalBottomSheetValue.Expanded), + onBack = { + scope.launch{ + state.animateTo(ModalBottomSheetValue.Hidden, tween(300)) + } + } + ) + } + + + } @@ -75,6 +125,7 @@ fun ConversationContent( //.nestedScroll(scrollBehavior.nestedScrollConnection) ) { Messages( + users = uiState.users, messages = uiState.messages, navigateToProfile = navigateToProfile, modifier = Modifier.weight(1f), diff --git a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/ChattingDetailViewModel.kt b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/ChattingDetailViewModel.kt index 674378f1..57e2c9b2 100644 --- a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/ChattingDetailViewModel.kt +++ b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/ChattingDetailViewModel.kt @@ -1,7 +1,7 @@ package com.d_vide.D_VIDE.app.presentation.view.ChattingDetail import android.util.Log -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.* import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -9,6 +9,7 @@ import com.d_vide.D_VIDE.app.domain.model.ChatUserInfo import com.d_vide.D_VIDE.app.domain.model.ConversationUiState import com.d_vide.D_VIDE.app.domain.model.Message import com.d_vide.D_VIDE.app.presentation.navigation.DetailDestinationKey +import com.d_vide.D_VIDE.app.presentation.state.UserInformation import com.google.firebase.database.DataSnapshot import com.google.firebase.database.DatabaseError import com.google.firebase.database.FirebaseDatabase @@ -30,17 +31,19 @@ class ChattingDetailViewModel @Inject constructor( private val databaseReference = firebaseDatabase.reference - private var _state = mutableStateOf(ConversationUiState()) - val state = _state + var state by mutableStateOf(ConversationUiState()) + private set - private var userId = "ascdf" + var user by mutableStateOf(UserInformation.userInfo) + private set + var userId by mutableStateOf(user.userId.toString() + "userId") private var chatId = savedStateHandle.get(DetailDestinationKey.CHATTING)!! init { + getTitle() getChattingInfo() getUsersInfo() - getTitle() } //채팅 불러오기 user.id @@ -55,7 +58,7 @@ class ChattingDetailViewModel @Inject constructor( for (c in snapshot.children) { mList.add(0, c.getValue(Message::class.java) ?: Message("", "")) } - _state.value = ConversationUiState(messages = mList) + state = state.copy(messages = mList) //메세지 읽음(false로 수정) changeUnRead(userId, unRead = false) } @@ -86,8 +89,8 @@ class ChattingDetailViewModel @Inject constructor( override fun onDataChange(snapshot: DataSnapshot) { viewModelScope.launch { - _state.value.users = snapshot.getValue>()!! - Log.d("가희1", _state.value.users.toString()) + state = state.copy(users = snapshot.getValue>()!!) + Log.d("가희1", state.users.toString()) } } @@ -106,8 +109,8 @@ class ChattingDetailViewModel @Inject constructor( override fun onDataChange(snapshot: DataSnapshot) { viewModelScope.launch { - _state.value.channelName = snapshot.getValue() ?: "title" - Log.d("가희1", _state.value.users.toString()) + state = state.copy(channelName = snapshot.getValue() ?: "title") + Log.d("가희1", state.channelName) } } @@ -122,11 +125,14 @@ class ChattingDetailViewModel @Inject constructor( * 메세지를 보내는 함수 * @param msg 보내려는 메세지 */ - fun send(msg: Message) { + fun send(content: String) { //메세지 안읽음(true)로 수정 - state.value.users.forEach { + state.users.forEach { changeUnRead(it.key, unRead = true) } + + var msg = Message(userId, content, System.currentTimeMillis()) + //메세지 보내기 databaseReference.child("chatrooms") .child("$chatId") diff --git a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/component/Message.kt b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/component/Message.kt index 0edbb6d3..56bdb25f 100644 --- a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/component/Message.kt +++ b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/ChattingDetail/component/Message.kt @@ -43,13 +43,16 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import com.d_vide.D_VIDE.R +import com.d_vide.D_VIDE.app.domain.model.ChatUserInfo import com.d_vide.D_VIDE.app.domain.model.Message +import com.d_vide.D_VIDE.app.presentation.state.UserInformation import com.d_vide.D_VIDE.app.presentation.util.convertTimestampToTime import com.d_vide.D_VIDE.ui.theme.* import kotlinx.coroutines.launch @Composable fun Messages( + users: MutableMap, messages: List, navigateToProfile: (String) -> Unit, scrollState: LazyListState, @@ -59,7 +62,7 @@ fun Messages( Box(modifier = modifier) { //자신의 아이디값을 얻음 - val authorMe = "authorMe" + val authorMe by mutableStateOf(UserInformation.userInfo.userId.toString() + "userId") LazyColumn( reverseLayout = true, state = scrollState, @@ -92,6 +95,7 @@ fun Messages( //메세지 보여주는 곳 item { Message( + author = users[content.author]?.nickname ?: "", onAuthorClick = { name -> navigateToProfile(name) }, msg = content, isUserMe = content.author == authorMe, @@ -133,6 +137,7 @@ fun Messages( @Composable fun Message( + author: String = "", onAuthorClick: (String) -> Unit, msg: Message, isUserMe: Boolean, @@ -151,7 +156,7 @@ fun Message( // 프로필 사진 Image( modifier = Modifier - .clickable(onClick = { onAuthorClick(msg.author) }) + .clickable(onClick = { onAuthorClick(msg.author.replace("userId", "")) }) .padding(horizontal = 16.dp) .size(42.dp) .clip(CircleShape) @@ -165,6 +170,7 @@ fun Message( Spacer(modifier = Modifier.width(74.dp)) } AuthorAndTextMessage( + author = author, msg = msg, isUserMe = isUserMe, isFirstMessageByAuthor = isFirstMessageByAuthor, @@ -179,6 +185,7 @@ fun Message( @Composable fun AuthorAndTextMessage( + author: String = "", msg: Message, isUserMe: Boolean, isFirstMessageByAuthor: Boolean, @@ -189,7 +196,7 @@ fun AuthorAndTextMessage( Column(modifier = modifier) { if (isLastMessageByAuthor && !isUserMe) { - AuthorName(msg) + AuthorName(author) } Row(Modifier.align(if (isUserMe) Alignment.End else Alignment.Start)) { if (isUserMe) { @@ -224,11 +231,11 @@ fun AuthorAndTextMessage( * 보낸 사람을 표시 하는 부분 */ @Composable -private fun AuthorName(msg: Message) { +private fun AuthorName(author: String) { // Combine author and timestamp for a11y. Row(modifier = Modifier.semantics(mergeDescendants = true) {}) { Text( - text = msg.author, + text = author, style = MaterialTheme.typography.titleMedium, modifier = Modifier .alignBy(LastBaseline) diff --git a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/Chattings/ChattingsViewModel.kt b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/Chattings/ChattingsViewModel.kt index 33f2f3db..754b7245 100644 --- a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/Chattings/ChattingsViewModel.kt +++ b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/Chattings/ChattingsViewModel.kt @@ -1,12 +1,16 @@ package com.d_vide.D_VIDE.app.presentation.view.Chattings import android.util.Log +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.d_vide.D_VIDE.app.domain.model.Chat import com.d_vide.D_VIDE.app.domain.model.ConversationUiState import com.d_vide.D_VIDE.app.domain.model.Message +import com.d_vide.D_VIDE.app.presentation.state.UserInformation import com.google.firebase.database.DataSnapshot import com.google.firebase.database.DatabaseError import com.google.firebase.database.FirebaseDatabase @@ -17,12 +21,17 @@ import javax.inject.Inject @HiltViewModel class ChattingsViewModel @Inject constructor( + ) : ViewModel() { private val firebaseDatabase = FirebaseDatabase.getInstance() private val databaseReference = firebaseDatabase.reference var chatList : MutableList> = mutableStateListOf() - var userId: String = "ascdf" + + var user by mutableStateOf(UserInformation.userInfo) + private set + + var userId by mutableStateOf(user.userId.toString() + "userId") init { getChattingRoom() diff --git a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/PostRecruiting/PostRecruitingViewModel.kt b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/PostRecruiting/PostRecruitingViewModel.kt index 3f6df392..4b78dd12 100644 --- a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/PostRecruiting/PostRecruitingViewModel.kt +++ b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/PostRecruiting/PostRecruitingViewModel.kt @@ -13,6 +13,7 @@ import com.d_vide.D_VIDE.app.domain.use_case.PostRecruiting import com.d_vide.D_VIDE.app.domain.util.Resource import com.d_vide.D_VIDE.app.domain.util.UriUtil.toFile import com.d_vide.D_VIDE.app.domain.util.log +import com.d_vide.D_VIDE.app.presentation.state.UserInformation import com.google.android.gms.maps.model.CameraPosition import com.google.android.gms.maps.model.LatLng import com.google.firebase.database.FirebaseDatabase @@ -41,7 +42,9 @@ class PostRecruitingViewModel @Inject constructor( private var _postId = mutableStateOf(0) val postId: State = _postId - private var userId = "ascdf" + var user by mutableStateOf(UserInformation.userInfo) + private set + var userId by mutableStateOf(user.userId.toString() + "userId") private var _recruitingBody = mutableStateOf(RecruitingBodyDTO()) val recruitingBodyDTO: State = _recruitingBody @@ -136,13 +139,15 @@ class PostRecruitingViewModel @Inject constructor( when (it) { is Resource.Success -> { it.data!!.postId.also { _postId.value = it } - Log.d("가희", "모집글 올리기 성공 postId: ${it.data!!.postId}") + Log.d("가희", "모집글 올리기 성공 postId: ${it.data!!.postId} ${user.nickname}") _eventFlow.emit(UiEvent.SaveRecruiting(it.data.postId.toLong())) + var chatUserInfo = ChatUserInfo(userId, user.nickname,false) + //채팅방 생성 databaseReference.child("chatrooms") .child("${it.data.postId}") - .child("users/$userId").setValue(ChatUserInfo(userId,"nickname",false)) + .child("users/$userId").setValue(chatUserInfo) databaseReference.child("chatrooms") .child("${it.data.postId}") diff --git a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/RecruitingDetail/PostRecruitingOrderViewModel.kt b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/RecruitingDetail/PostRecruitingOrderViewModel.kt index 4c94eca1..e801a031 100644 --- a/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/RecruitingDetail/PostRecruitingOrderViewModel.kt +++ b/app/src/main/java/com/d_vide/D_VIDE/app/presentation/view/RecruitingDetail/PostRecruitingOrderViewModel.kt @@ -3,9 +3,7 @@ package com.d_vide.D_VIDE.app.presentation.view.RecruitingDetail import android.content.Context import android.net.Uri import android.util.Log -import androidx.compose.runtime.State -import androidx.compose.runtime.mutableStateListOf -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.* import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -14,6 +12,7 @@ import com.d_vide.D_VIDE.app.domain.model.ChatUserInfo import com.d_vide.D_VIDE.app.domain.use_case.PostRecruitingOrder import com.d_vide.D_VIDE.app.domain.util.Resource import com.d_vide.D_VIDE.app.domain.util.UriUtil +import com.d_vide.D_VIDE.app.presentation.state.UserInformation import com.d_vide.D_VIDE.app.presentation.view.PostRecruiting.PostRecruitingsEvent import com.google.firebase.database.FirebaseDatabase import dagger.hilt.android.lifecycle.HiltViewModel @@ -47,9 +46,9 @@ class PostRecruitingOrderViewModel @Inject constructor( private val firebaseDatabase = FirebaseDatabase.getInstance() private val databaseReference = firebaseDatabase.reference - //유저의 아이디 넣는 곳 - //차후 수정 필요 - var userId = "userId" + var user by mutableStateOf(UserInformation.userInfo) + private set + var userId by mutableStateOf(user.userId.toString() + "userId") fun onEvent(event: PostRecruitingOrderEvent){ when (event) { @@ -129,7 +128,7 @@ class PostRecruitingOrderViewModel @Inject constructor( is PostRecruitingOrderEvent.EnterChatting -> { databaseReference.child("chatrooms") .child("${event.value}") - .child("users/$userId").setValue(ChatUserInfo(userId,"nickname",false)) + .child("users/$userId").setValue(ChatUserInfo(userId,user.nickname,false)) viewModelScope.launch { _eventFlow.emit(