From 1bfbad33d2bd222702c6afa19c9748aa1e1cf171 Mon Sep 17 00:00:00 2001 From: Seungmin-develop Date: Thu, 24 Mar 2022 21:28:40 +0900 Subject: [PATCH] [feat] #111 Chatting Connection --- app/src/main/AndroidManifest.xml | 4 +- .../view/fragment/CategoryViewIdeaFragment.kt | 7 +- .../infraandroid/chat/model/ChatRoomDB.kt | 29 ------- .../infraandroid/chat/model/ChatRoomDao.kt | 14 ---- .../infraandroid/chat/model/ChatRoomEntity.kt | 11 --- .../infraandroid/chat/model/MessageInfo.kt | 1 + .../infraandroid/chat/view/ChatFragment.kt | 81 +++++++++++-------- .../chat/view/ChatMultiViewAdapter.kt | 4 +- .../chat/view/ChattingRoomAdapter.kt | 8 +- app/src/main/res/navigation/nav_graph.xml | 5 ++ .../main/res/xml/data_extraction_rules.xml | 36 +++++++++ 11 files changed, 103 insertions(+), 97 deletions(-) delete mode 100644 app/src/main/java/com/example/infraandroid/chat/model/ChatRoomDB.kt delete mode 100644 app/src/main/java/com/example/infraandroid/chat/model/ChatRoomDao.kt delete mode 100644 app/src/main/java/com/example/infraandroid/chat/model/ChatRoomEntity.kt create mode 100644 app/src/main/res/xml/data_extraction_rules.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5eef832..0df362a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,14 +12,14 @@ + android:requestLegacyExternalStorage="true" + android:dataExtractionRules="@xml/data_extraction_rules"> (R.layout.fragment_view_idea){ private var writerId : String ?= null + private var opponentProfileImg : String ?= null override fun FragmentViewIdeaBinding.onCreateView(){ @@ -52,7 +53,9 @@ class CategoryViewIdeaFragment : BaseFragment(R.layout. if(response.isSuccessful){ when(response.body()?.code){ 1000 -> { binding.viewIdea = response.body()?.result - writerId = response.body()?.result?.user_nickname } + writerId = response.body()?.result?.user_nickname + opponentProfileImg = response.body()?.result?.user_prPhoto + } } } } @@ -63,7 +66,7 @@ class CategoryViewIdeaFragment : BaseFragment(R.layout. }) binding.startChattingImageButton.setOnClickListener { - val action = CategoryViewIdeaFragmentDirections.actionCategoryViewIdeaFragmentToChatFragment(writerId = writerId) + val action = CategoryViewIdeaFragmentDirections.actionCategoryViewIdeaFragmentToChatFragment(writerId = writerId, opponentProfileImg) it.findNavController().navigate(action) } diff --git a/app/src/main/java/com/example/infraandroid/chat/model/ChatRoomDB.kt b/app/src/main/java/com/example/infraandroid/chat/model/ChatRoomDB.kt deleted file mode 100644 index 5ea1533..0000000 --- a/app/src/main/java/com/example/infraandroid/chat/model/ChatRoomDB.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.example.infraandroid.chat.model - -import android.content.Context -import androidx.room.Database -import androidx.room.Room -import androidx.room.RoomDatabase - -@Database(entities = [ChatRoomEntity::class], version = 1) -abstract class ChatRoomDB: RoomDatabase() { - abstract fun chatRoomDAO(): ChatRoomDao - - companion object{ - private var INSTANCE: ChatRoomDB? = null - - @Synchronized - fun getInstance(context: Context): ChatRoomDB? { - if (INSTANCE == null) { - synchronized(ChatRoomDB::class) { - INSTANCE = Room.databaseBuilder( - context.applicationContext, - ChatRoomDB::class.java, - "chatRoomDB" - ).build() - } - } - return INSTANCE - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/infraandroid/chat/model/ChatRoomDao.kt b/app/src/main/java/com/example/infraandroid/chat/model/ChatRoomDao.kt deleted file mode 100644 index 323db8c..0000000 --- a/app/src/main/java/com/example/infraandroid/chat/model/ChatRoomDao.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.example.infraandroid.chat.model - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.Query - -@Dao -interface ChatRoomDao { - @Query("SELECT * FROM CHATROOM WHERE opponentNickName = :opponentNickName") - fun checkOpponent(opponentNickName: String): List - - @Insert() - fun insert(chatRoom : ChatRoomEntity) -} \ No newline at end of file diff --git a/app/src/main/java/com/example/infraandroid/chat/model/ChatRoomEntity.kt b/app/src/main/java/com/example/infraandroid/chat/model/ChatRoomEntity.kt deleted file mode 100644 index c0c125c..0000000 --- a/app/src/main/java/com/example/infraandroid/chat/model/ChatRoomEntity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.infraandroid.chat.model - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "chatRoom") -data class ChatRoomEntity ( - @PrimaryKey(autoGenerate = true) var index: Int?, - @ColumnInfo(name = "opponentNickName") var opponentNickName: String?) { -} \ No newline at end of file diff --git a/app/src/main/java/com/example/infraandroid/chat/model/MessageInfo.kt b/app/src/main/java/com/example/infraandroid/chat/model/MessageInfo.kt index e50ce26..1f1a73f 100644 --- a/app/src/main/java/com/example/infraandroid/chat/model/MessageInfo.kt +++ b/app/src/main/java/com/example/infraandroid/chat/model/MessageInfo.kt @@ -4,5 +4,6 @@ data class MessageInfo( var senderId: String = "", var message: String = "", var sendTime : String = "", + var profileImg : String? = "", var dateLine : Boolean = true, ) diff --git a/app/src/main/java/com/example/infraandroid/chat/view/ChatFragment.kt b/app/src/main/java/com/example/infraandroid/chat/view/ChatFragment.kt index 662ffcf..3855bc4 100644 --- a/app/src/main/java/com/example/infraandroid/chat/view/ChatFragment.kt +++ b/app/src/main/java/com/example/infraandroid/chat/view/ChatFragment.kt @@ -10,22 +10,14 @@ import android.widget.Toast import androidx.fragment.app.Fragment import androidx.navigation.findNavController import androidx.navigation.fragment.navArgs -import androidx.room.Room import com.example.infraandroid.util.InfraApplication import com.example.infraandroid.R -import com.example.infraandroid.chat.model.ChatRoomDB -import com.example.infraandroid.chat.model.ChatRoomEntity import com.example.infraandroid.chat.model.MessageInfo import com.example.infraandroid.databinding.FragmentChatBinding -import com.google.firebase.database.ChildEventListener -import com.google.firebase.database.DataSnapshot -import com.google.firebase.database.DatabaseError +import com.google.firebase.database.* import com.google.firebase.database.ktx.database import com.google.firebase.database.ktx.getValue import com.google.firebase.ktx.Firebase -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch import java.text.SimpleDateFormat import java.util.* import kotlin.collections.HashMap @@ -36,8 +28,9 @@ class ChatFragment : Fragment() { private val chatAdapter = ChatMultiViewAdapter() private val database = Firebase.database val chatList = mutableListOf() - private var chatRoomDB : ChatRoomDB? = null - + private var chatRoomIndex : Int? = null + private val mRef = database.getReference("chatting") + private val args: ChatFragmentArgs by navArgs() override fun onCreateView( inflater: LayoutInflater, @@ -47,17 +40,20 @@ class ChatFragment : Fragment() { val binding = FragmentChatBinding.inflate(inflater, container, false) mBinding = binding + return mBinding?.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val args: ChatFragmentArgs by navArgs() val opponentNickName = args.writerId + val opponentProfileImg = args.opponenetProfileImg + val buttonToSend = mBinding?.messageSendButton as ImageButton mBinding?.chatOpponentNameTextview?.text = opponentNickName + // 리사이클러뷰 mBinding?.chatRecyclerview?.adapter = chatAdapter @@ -66,11 +62,10 @@ class ChatFragment : Fragment() { var date = "" override fun onChildAdded(dataSnapshot: DataSnapshot, previousChildName: String?) { - // A new comment has been added, add it to the displayed list chatList.clear() - val tempMessage = MessageInfo("","","") + val tempMessage = MessageInfo("","","", opponentProfileImg) for(snapshot in dataSnapshot.children){ - Log.d(TAG, "onChildAdded: "+ snapshot.key.toString()) + Log.d(TAG, "onChildAdded: ${snapshot.value.toString()}") if(snapshot.key=="senderId"){ tempMessage.senderId=snapshot.value.toString() } @@ -87,12 +82,12 @@ class ChatFragment : Fragment() { date = thisMessageTime } } -// if(snapshot.key=="user1") { -// opponentId = snapshot.value.toString() -// } } if(tempMessage.senderId!="" && tempMessage.message!="" && tempMessage.sendTime!="") + { + Log.d(TAG, "onChildAdded: $tempMessage") chatList.add(tempMessage) + } chatAdapter.messageList.addAll(chatList) chatAdapter.notifyDataSetChanged() // ... @@ -138,24 +133,39 @@ class ChatFragment : Fragment() { } } - var chatRoomIndex : Int ?= null - chatRoomDB = ChatRoomDB.getInstance(context!!.applicationContext) - CoroutineScope(Dispatchers.IO).launch{ - if (opponentNickName != null) { - if (chatRoomDB!!.chatRoomDAO().checkOpponent(opponentNickName).isEmpty()){ - var newChatRoomEntity : ChatRoomEntity ?= null - newChatRoomEntity?.opponentNickName = opponentNickName - if (newChatRoomEntity != null) { - chatRoomDB!!.chatRoomDAO().insert(newChatRoomEntity) + + mRef.addValueEventListener(object:ValueEventListener{ + override fun onDataChange(snapshot: DataSnapshot) { + // 이미 파이어베이스에 존재하는 채팅방인지 검사 + if(chatRoomIndex==null){ + var i = 0 + for(chatIndex in snapshot.children){ + i += 1 + if(chatIndex.child("users").child("user1").value.toString()==opponentNickName && + chatIndex.child("users").child("user2").value.toString()==InfraApplication.prefs.getString("userNickName", "null")){ + chatRoomIndex = i + break + } + if(chatIndex.child("users").child("user2").value.toString()==opponentNickName && + chatIndex.child("users").child("user1").value.toString()==InfraApplication.prefs.getString("userNickName", "null")){ + chatRoomIndex = i + break + } + } + // 처음 시작하는 채팅이면 + if(chatRoomIndex==null){ + chatRoomIndex = snapshot.childrenCount.toInt()+1 } - chatRoomIndex = chatRoomDB!!.chatRoomDAO().checkOpponent(opponentNickName)[0].index + mRef.child(chatRoomIndex.toString()).addChildEventListener(childEventListener) + Log.d(TAG, "onDataChange: $chatRoomIndex") } } - } + override fun onCancelled(error: DatabaseError) { + TODO("Not yet implemented") + } - val databaseReference = database.getReference("chatting").child(chatRoomIndex.toString()) - databaseReference.addChildEventListener(childEventListener) + }) // 보내기 버튼을 누르면 firebase realtime db에 저장 buttonToSend.setOnClickListener { @@ -164,17 +174,18 @@ class ChatFragment : Fragment() { val date = Date(now) val dataFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") val dateTime = dataFormat.format(date) - val myRef = database.getReference("chatting").child(chatRoomIndex.toString()).child(dateTime) + Log.d(TAG, "왜 여기는 되냐 "+mRef.child(chatRoomIndex.toString())) + val myRef = mRef.child(chatRoomIndex.toString()).child(dateTime) // 대화하는 두 사람의 Id값을 firebase realtime db에 저장 - val userRef = database.getReference("chatting").child(chatRoomIndex.toString()).child("users") - val lastMessageRef = database.getReference("chatting").child(chatRoomIndex.toString()).child("lastMessage") + val userRef = mRef.child(chatRoomIndex.toString()).child("users") + val lastMessageRef = mRef.child(chatRoomIndex.toString()).child("lastMessage") val userHashMap = HashMap() userHashMap["user1"] = InfraApplication.prefs.getString("userNickName", "null") // 상대방의 아이디 가져와서 user2에 저장 userHashMap["user2"] = opponentNickName.toString() userHashMap["user1ProfileImg"] = "user1의 프로필 이미지 url" - userHashMap["user2ProfileImg"] = "user2의 프로필 이미지 url" + userHashMap["user2ProfileImg"] = opponentProfileImg.toString() userRef.setValue(userHashMap) if (messageToSend != null) { diff --git a/app/src/main/java/com/example/infraandroid/chat/view/ChatMultiViewAdapter.kt b/app/src/main/java/com/example/infraandroid/chat/view/ChatMultiViewAdapter.kt index 99b5afc..230a375 100644 --- a/app/src/main/java/com/example/infraandroid/chat/view/ChatMultiViewAdapter.kt +++ b/app/src/main/java/com/example/infraandroid/chat/view/ChatMultiViewAdapter.kt @@ -68,7 +68,9 @@ class ChatMultiViewAdapter() : RecyclerView.Adapter(){ } Glide.with(itemView) - .load(R.drawable.other_user_photo) + .load(messageInfo.profileImg) + .circleCrop() + .error(R.drawable.other_user_photo) .into(binding.opponentProfileImageview) var hour = messageInfo.sendTime.substring(11..12) diff --git a/app/src/main/java/com/example/infraandroid/chat/view/ChattingRoomAdapter.kt b/app/src/main/java/com/example/infraandroid/chat/view/ChattingRoomAdapter.kt index 4a54545..146afd2 100644 --- a/app/src/main/java/com/example/infraandroid/chat/view/ChattingRoomAdapter.kt +++ b/app/src/main/java/com/example/infraandroid/chat/view/ChattingRoomAdapter.kt @@ -36,11 +36,13 @@ class ChattingRoomAdapter(): RecyclerView.Adapter() { binding.chattingRoomLastMessageTextview.text = chattingRoomInfo.lastMessage binding.chattingRoomListOpponentNameTextview.text = chattingRoomInfo.opponentName Glide.with(itemView) - .load(R.drawable.other_user_photo) + .load(chattingRoomInfo.opponentProfileImg) + .circleCrop() + .error(R.drawable.other_user_photo) .into(binding.chattingRoomListImageview) itemView.setOnClickListener { - InfraApplication.chatRoomIndex = chattingRoomInfo.chattingRoomIndex - it.findNavController().navigate(R.id.action_chatting_room_list_fragment_to_chat_fragment) + val action = ChattingRoomListFragmentDirections.actionChattingRoomListFragmentToChatFragment(chattingRoomInfo.opponentName, chattingRoomInfo.opponentProfileImg) + it.findNavController().navigate(action) } val now: Long = System.currentTimeMillis() diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index d2c41d0..99cf116 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -51,6 +51,11 @@ app:argType="string" app:nullable="true" android:defaultValue="@null"/> + + + + + + + + \ No newline at end of file