저번 포스팅에서 실시간으로 메시지를 주고 받는 기능까지 추가해보았습니다. 그러나 현재 상태로는 새로운 메시지가 도착했는지 알 수 없습니다. 그래서 이번 포스팅에서는 새로운 메시지가 있음을 알려주는 기능과 메시지를 읽지 않은 유저의 수를 표시하는 기능을 추가해보겠습니다.
각 채팅방마다 본인이 읽지 않은 메시지의 개수를 확인할 수 있는 기능을 추가하자.
① MessageModel에 readerUid 필드를 추가한다.
val readerUids: MutableMap<String, Boolean> = mutableMapOf(),
② ChatRoom에 unreadCount 필드를 추가한다.
val unreadCount : Int? = 0
③ chat_listview_item.xml 파일을 아래와 같이 수정한다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/list_border"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/lvChatRoomName"
android:text="ChatRoom Name"
android:textStyle="bold"
android:textColor="#000000"
android:textSize="20sp"
android:layout_marginLeft="20dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="@+id/unreadMessageContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:visibility="gone"
android:background="@drawable/message_box">
<TextView
android:id="@+id/unreadMessageCountTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:gravity="center"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="5dp"
android:textSize="20sp"
android:textColor="#000000" />
</FrameLayout>
</LinearLayout>
<TextView
android:id="@+id/lvUserListArea"
android:text="User List"
android:textSize="15sp"
android:layout_marginHorizontal="40dp"
android:layout_marginBottom="20dp"
android:maxWidth="170dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
④ ChatListFragment의 getChatRoomList를 아래와 같이 수정하고, getUnreadMessageCount 메서드를 추가한다.
private fun getChatRoomList() {
val postListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
chatRoomList.clear()
for (datamModel in dataSnapshot.children) {
val chatRoom = datamModel.getValue(ChatRoom::class.java)
chatRoomList.add(chatRoom!!)
}
for(chatRoom in chatRoomList) {
getUnreadMessageCount(chatRoom.chatRoomId!!)
}
listViewAdapter.notifyDataSetChanged()
}
override fun onCancelled(databseError: DatabaseError) {
Log.w("MyMessage", "onCancelled", databseError.toException())
}
}
FirebaseRef.chatRoom.child(FirebaseAuthUtils.getUid()).addValueEventListener(postListener)
}
private fun getUnreadMessageCount(chatRoomId : String) {
val postListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
var count = 0
for (datamModel in dataSnapshot.children) {
val uidList = datamModel.child("readerUid").getValue(object : GenericTypeIndicator<MutableMap<String, Boolean>>() {})
if (uidList != null) {
Log.d("readerUid", uidList.toString())
if (!uidList.containsKey(FirebaseAuthUtils.getUid())) {
// readerUid에 내 uid가 없으면
count++
}
}
}
FirebaseRef.chatRoom.child(FirebaseAuthUtils.getUid()).child(chatRoomId).child("unreadCount").setValue(count)
}
override fun onCancelled(databaseError: DatabaseError) {
Log.w("MyMessage", "onCancelled", databaseError.toException())
}
}
FirebaseRef.message.child(chatRoomId).addValueEventListener(postListener)
}
⑤ ChatRoomAdapter를 아래와 같이 수정한다.
class ChatRoomAdapter(private val context: Context, private val dataList : List<ChatRoom>) : BaseAdapter() {
override fun getCount(): Int {
return dataList.size
}
override fun getItem(position: Int): Any {
return dataList[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var convertView = convertView
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.chat_listview_item, parent, false)
}
val listViewChatRoomName = convertView?.findViewById<TextView>(R.id.lvChatRoomName)
val listViewUserList = convertView?.findViewById<TextView>(R.id.lvUserListArea)
val listViewUnreadCount = convertView?.findViewById<TextView>(R.id.unreadMessageCountTextView)
val unreadMessageContainer = convertView?.findViewById<FrameLayout>(R.id.unreadMessageContainer)
listViewUnreadCount!!.text = dataList[position].unreadCount.toString()
val unreadCount = listViewUnreadCount!!.text.toString().toInt()
if (unreadCount > 0) {
unreadMessageContainer!!.visibility = View.VISIBLE
listViewUnreadCount.visibility = View.VISIBLE
} else {
unreadMessageContainer!!.visibility = View.GONE
listViewUnreadCount.visibility = View.GONE
}
listViewChatRoomName!!.text = dataList[position].roomName
listViewUserList!!.text = dataList[position].userList
return convertView!!
}
}
⑥ 채팅방에 들어가면 모든 메시지의 readerUid Mutable Map에 본인의 UID를 추가해야 한다. ChatRoomActivity를 아래와 같이 수정한다.
class ChatRoomActivity : AppCompatActivity() {
lateinit var count : String
lateinit var messageAdapter : MessageAdapter
lateinit var recyclerView : RecyclerView
val messageList = mutableListOf<MessageModel>()
val readerUidMap = mutableMapOf<String, Boolean>()
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat_room)
readerUidMap[FirebaseAuthUtils.getUid()] = true
val roomName = findViewById<TextView>(R.id.chatRoomName)
val nickNameList = findViewById<TextView>(R.id.nickNameList)
val inviteBtn = findViewById<Button>(R.id.invite)
val userCount = findViewById<TextView>(R.id.userCount)
// Intent로부터 데이터를 가져옴
val chatRoomName = intent.getStringExtra("chatRoomName")
roomName.text = chatRoomName
val roomId = intent.getStringExtra("chatRoomId")
val chatRoomId = roomId
val userList = intent.getStringExtra("userList")
nickNameList.text = userList
CoroutineScope(Dispatchers.IO).launch {
val response = getUserCount(chatRoomId!!)
Log.d("userCount", response.toString())
if (response.isSuccess) {
count = response.result.toString()
userCount.text = count
} else {
Log.d("UserListFragment", "유저의 정보를 불러오지 못함")
}
}
recyclerView = findViewById<RecyclerView>(R.id.messageRV)
messageAdapter = MessageAdapter(this, messageList)
recyclerView.adapter = messageAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
getMessageList(chatRoomId!!)
Log.d("MessageList", messageList.toString())
inviteBtn.setOnClickListener {
val intent = Intent(this, InviteActivity::class.java)
intent.putExtra("chatRoomId", chatRoomId)
intent.putExtra("chatRoomName", chatRoomName)
intent.putExtra("nickNameList", userList)
startActivity(intent)
}
val participantBtn = findViewById<ImageView>(R.id.participants)
participantBtn.setOnClickListener {
val intent = Intent(this, ParticipantsActivity::class.java)
intent.putExtra("chatRoomId", chatRoomId)
startActivity(intent)
}
val message = findViewById<TextInputEditText>(R.id.message)
val sendBtn = findViewById<ImageView>(R.id.send)
lateinit var myNickName : String
lateinit var myProfileUrl : String
lateinit var messageModel: MessageModel
val myUid = FirebaseAuthUtils.getUid()
sendBtn.setOnClickListener {
val contents = message.text.toString()
val sendTime = getSendTime()
CoroutineScope(Dispatchers.IO).launch {
val response = getUserInfo(myUid)
if (response.isSuccess) {
myNickName = response.result?.nickName.toString()
myProfileUrl = response.result?.imgUrl.toString()
val readerUids = mutableMapOf<String, Boolean>()
messageModel = MessageModel(myUid, myNickName, myProfileUrl, contents, sendTime, readerUids)
FirebaseRef.message.child(chatRoomId!!).push().setValue(messageModel)
} else {
Log.d("ChatRoomActivity", "유저의 정보를 불러오지 못함")
}
}
message.text?.clear()
}
}
override fun onBackPressed() {
readerUidMap.remove(FirebaseAuthUtils.getUid())
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
private suspend fun getUserCount(roomId: String) : BaseResponse<String> {
return RetrofitInstance.chatApi.getUserCount(roomId)
}
private suspend fun getUserInfo(uid: String): BaseResponse<GetUserRes> {
return RetrofitInstance.myPageApi.getUserInfo(uid)
}
//메시지 보낸 시각 정보 반환
@RequiresApi(Build.VERSION_CODES.O)
private fun getSendTime(): String {
try {
val localDateTime = LocalDateTime.now()
val dateTimeFormatter = DateTimeFormatter.ofPattern("M/d h:mm a")
return localDateTime.format(dateTimeFormatter)
} catch (e: Exception) {
e.printStackTrace()
throw Exception("시간 정보를 불러오지 못함")
}
}
private fun getMessageList(chatRoomId: String) {
val postListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
messageList.clear()
val newMessages = mutableListOf<MessageModel>() // 새로운 메시지를 저장할 리스트 생성
for (dataModel in dataSnapshot.children) {
val messageModel = dataModel.getValue(MessageModel::class.java)
if (messageModel != null) {
if (messageModel.senderUid != FirebaseAuthUtils.getUid()) {
messageModel.viewType = MessageModel.VIEW_TYPE_YOU
}
// 새로운 메시지 ID 생성
val messageId = dataModel.key
if (messageId != null) {
FirebaseRef.message.child(chatRoomId!!).child(messageId).child("readerUid")
.updateChildren(readerUidMap as Map<String, Boolean>)
}
newMessages.add(messageModel)
}
}
messageList.addAll(newMessages)
messageAdapter.notifyDataSetChanged()
Log.d("MessageList", messageList.toString())
recyclerView.post {
recyclerView.scrollToPosition(recyclerView.adapter?.itemCount?.minus(1) ?: 0)
}
}
override fun onCancelled(databaseError: DatabaseError) {
Log.w("MyMessage", "onCancelled", databaseError.toException())
}
}
FirebaseRef.message.child(chatRoomId).addValueEventListener(postListener)
}
}
코드를 실행시켜보면, 읽지 않은 메시지의 개수가 실시간으로 추가되는 것을 확인해 볼 수 있을 것이다. 또한 채팅방에 들어갔다가 나오면, 채팅방의 모든 메시지를 읽은 것으로 처리해야 한다.
① message_recycler_view_item.xml 파일을 아래와 같이 수정한다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/messageContentsArea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:layout_marginEnd="8dp"
android:background="@drawable/message_box"
android:ellipsize="end"
android:maxWidth="230dp"
android:padding="10dp"
android:text="my text message"
android:textSize="15sp"
app:layout_constraintEnd_toStartOf="@+id/messageProfileArea"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/unreadUserCountContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/messageContentsArea">
<TextView
android:id="@+id/unreadUserCountTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:layout_marginBottom="20dp"
android:gravity="center"
android:text="10"
android:textColor="#ffd400"
android:textSize="10sp" />
</FrameLayout>
<TextView
android:id="@+id/dateTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginEnd="15dp"
android:text="9/7 7:01 AM"
android:textSize="10sp"
app:layout_constraintEnd_toStartOf="@+id/messageProfileArea"
app:layout_constraintTop_toBottomOf="@+id/messageContentsArea" />
<ImageView
android:id="@+id/messageProfileArea"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginTop="15dp"
android:layout_marginRight="15dp"
android:src="@drawable/profile"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/messageNickName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="17dp"
android:layout_marginBottom="2dp"
android:gravity="center"
android:text="nickname"
android:textColor="@color/black"
android:textSize="15sp"
app:layout_constraintBottom_toTopOf="@+id/messageContentsArea"
app:layout_constraintEnd_toStartOf="@+id/messageProfileArea" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
② message_recycler_view_item2.xml도 마찬가지로 수정해준다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/messageContentsArea2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="35dp"
android:background="@drawable/your_message_box"
android:ellipsize="end"
android:maxWidth="230dp"
android:padding="10dp"
android:text="my text message"
android:textSize="12sp"
app:layout_constraintStart_toEndOf="@+id/messageProfileArea2"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/unreadUserCountContainer2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/messageContentsArea2">
<TextView
android:id="@+id/unreadUserCountTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:layout_marginBottom="20dp"
android:gravity="center"
android:text="10"
android:textColor="#ffd400"
android:textSize="10sp" />
</FrameLayout>
<TextView
android:id="@+id/dateTime2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="9/7 7:01 AM"
android:textSize="10sp"
android:layout_marginTop="5dp"
android:layout_marginStart="15dp"
app:layout_constraintStart_toEndOf="@+id/messageProfileArea2"
app:layout_constraintTop_toBottomOf="@+id/messageContentsArea2" />
<ImageView
android:id="@+id/messageProfileArea2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginTop="15dp"
android:layout_marginLeft="15dp"
android:src="@drawable/profile"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/messageNickName2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="17dp"
android:gravity="center"
android:text="nickname"
android:textColor="@color/black"
android:textSize="15sp"
app:layout_constraintBottom_toTopOf="@+id/messageContentsArea2"
app:layout_constraintStart_toEndOf="@+id/messageProfileArea2" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
③ MessageModel에 unreadUserCount 필드를 추가한다.
var unreadUserCount : Int = 0, // 메시지를 읽지 않은 사람의 수
④ MessageAdapter를 아래와 같이 수정한다.
class MessageAdapter(private val context: Context, val items: MutableList<MessageModel>)
: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class ItemViewHolder1(private val view: View) : RecyclerView.ViewHolder(view) {
val contents : TextView = view.findViewById(R.id.messageContentsArea)
val dateTime : TextView = view.findViewById(R.id.dateTime)
val nickName : TextView = view.findViewById(R.id.messageNickName)
val profile : ImageView = view.findViewById(R.id.messageProfileArea)
val unreadUserContainer : FrameLayout = view.findViewById(R.id.unreadUserCountContainer)
val unreadUserCount : TextView = view.findViewById(R.id.unreadUserCountTextView)
}
class ItemViewHolder2(private val view: View) : RecyclerView.ViewHolder(view) {
val contents : TextView = view.findViewById(R.id.messageContentsArea2)
val dateTime : TextView = view.findViewById(R.id.dateTime2)
val nickName : TextView = view.findViewById(R.id.messageNickName2)
val profile : ImageView = view.findViewById(R.id.messageProfileArea2)
val unreadUserContainer : FrameLayout = view.findViewById(R.id.unreadUserCountContainer2)
val unreadUserCount : TextView = view.findViewById(R.id.unreadUserCountTextView2)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val adapterLayout : View?
return when(viewType) {
MessageModel.VIEW_TYPE_ME -> {
adapterLayout = LayoutInflater.from(parent.context).inflate(R.layout.message_recycler_view_item, parent, false)
ItemViewHolder1(adapterLayout)
}
MessageModel.VIEW_TYPE_YOU -> {
adapterLayout = LayoutInflater.from(parent.context).inflate(R.layout.message_recycler_view_item2, parent, false)
ItemViewHolder2(adapterLayout)
}
else -> throw RuntimeException("Invalid View Type Error")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = items[position]
when (item.viewType) {
MessageModel.VIEW_TYPE_ME -> {
(holder as ItemViewHolder1).contents.text = item.contents
holder.dateTime.text = item.sendTime
holder.nickName.text = item.senderNickName
holder.unreadUserCount.text = item.unreadUserCount.toString()
if (item.unreadUserCount.toString().toInt() > 0) {
holder.unreadUserContainer!!.visibility = View.VISIBLE
holder.unreadUserCount.visibility = View.VISIBLE
} else {
holder.unreadUserContainer!!.visibility = View.GONE
holder.unreadUserCount.visibility = View.GONE
}
if (item.senderProfileUrl != "null") {
Glide.with(context)
.load(item.senderProfileUrl)
.into(holder.profile)
} else {
holder.profile.setImageResource(R.drawable.profile)
}
}
MessageModel.VIEW_TYPE_YOU -> {
(holder as ItemViewHolder2).contents.text = item.contents
holder.dateTime.text = item.sendTime
holder.nickName.text = item.senderNickName
holder.unreadUserCount.text = item.unreadUserCount.toString()
if (item.unreadUserCount.toString().toInt() > 0) {
holder.unreadUserContainer!!.visibility = View.VISIBLE
holder.unreadUserCount.visibility = View.VISIBLE
} else {
holder.unreadUserContainer!!.visibility = View.GONE
holder.unreadUserCount.visibility = View.GONE
}
if (item.senderProfileUrl != "null") {
Glide.with(context)
.load(item.senderProfileUrl)
.into(holder.profile)
} else {
holder.profile.setImageResource(R.drawable.profile)
}
}
}
}
override fun getItemCount(): Int {
return items.size
}
override fun getItemViewType(position: Int): Int {
return items[position].viewType
}
}
⑤ ChatRoomActivity를 아래와 같이 수정한다.
class ChatRoomActivity : AppCompatActivity() {
lateinit var count : String // 채팅방 참여 인원수
lateinit var messageAdapter : MessageAdapter
lateinit var recyclerView : RecyclerView
val messageList = mutableListOf<MessageModel>()
val readerUidMap = mutableMapOf<String, Boolean>()
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat_room)
readerUidMap[FirebaseAuthUtils.getUid()] = true
val roomName = findViewById<TextView>(R.id.chatRoomName)
val nickNameList = findViewById<TextView>(R.id.nickNameList)
val inviteBtn = findViewById<Button>(R.id.invite)
val userCount = findViewById<TextView>(R.id.userCount)
// Intent로부터 데이터를 가져옴
val chatRoomName = intent.getStringExtra("chatRoomName")
roomName.text = chatRoomName
val roomId = intent.getStringExtra("chatRoomId")
val chatRoomId = roomId
val userList = intent.getStringExtra("userList")
nickNameList.text = userList
CoroutineScope(Dispatchers.IO).launch {
val response = getUserCount(chatRoomId!!)
Log.d("userCount", response.toString())
if (response.isSuccess) {
count = response.result.toString()
userCount.text = count
} else {
Log.d("UserListFragment", "유저의 정보를 불러오지 못함")
}
}
recyclerView = findViewById<RecyclerView>(R.id.messageRV)
messageAdapter = MessageAdapter(this, messageList)
recyclerView.adapter = messageAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
getMessageList(chatRoomId!!)
Log.d("MessageList", messageList.toString())
inviteBtn.setOnClickListener {
val intent = Intent(this, InviteActivity::class.java)
intent.putExtra("chatRoomId", chatRoomId)
intent.putExtra("chatRoomName", chatRoomName)
intent.putExtra("nickNameList", userList)
startActivity(intent)
}
val participantBtn = findViewById<ImageView>(R.id.participants)
participantBtn.setOnClickListener {
val intent = Intent(this, ParticipantsActivity::class.java)
intent.putExtra("chatRoomId", chatRoomId)
startActivity(intent)
}
val message = findViewById<TextInputEditText>(R.id.message)
val sendBtn = findViewById<ImageView>(R.id.send)
lateinit var myNickName : String
lateinit var myProfileUrl : String
lateinit var messageModel: MessageModel
val myUid = FirebaseAuthUtils.getUid()
sendBtn.setOnClickListener {
val contents = message.text.toString()
if(contents.isEmpty()) {
Toast.makeText(this, "메시지를 입력해주세요", Toast.LENGTH_SHORT).show()
}
else {
val sendTime = getSendTime()
CoroutineScope(Dispatchers.IO).launch {
val response = getUserInfo(myUid)
if (response.isSuccess) {
myNickName = response.result?.nickName.toString()
myProfileUrl = response.result?.imgUrl.toString()
val readerUids = mutableMapOf<String, Boolean>()
messageModel = MessageModel(myUid, myNickName, myProfileUrl, contents,
sendTime, readerUids, 0)
Log.d("readerUid", readerUids.size.toString())
FirebaseRef.message.child(chatRoomId!!).push().setValue(messageModel)
} else {
Log.d("ChatRoomActivity", "유저의 정보를 불러오지 못함")
}
}
message.text?.clear()
}
}
}
override fun onBackPressed() {
readerUidMap.remove(FirebaseAuthUtils.getUid())
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
private suspend fun getUserCount(roomId: String) : BaseResponse<String> {
return RetrofitInstance.chatApi.getUserCount(roomId)
}
private suspend fun getUserInfo(uid: String): BaseResponse<GetUserRes> {
return RetrofitInstance.myPageApi.getUserInfo(uid)
}
//메시지 보낸 시각 정보 반환
@RequiresApi(Build.VERSION_CODES.O)
private fun getSendTime(): String {
try {
val localDateTime = LocalDateTime.now()
val dateTimeFormatter = DateTimeFormatter.ofPattern("M/d h:mm a")
return localDateTime.format(dateTimeFormatter)
} catch (e: Exception) {
e.printStackTrace()
throw Exception("시간 정보를 불러오지 못함")
}
}
private fun getMessageList(chatRoomId: String) {
val postListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
messageList.clear()
val newMessages = mutableListOf<MessageModel>() // 새로운 메시지를 저장할 리스트 생성
for (dataModel in dataSnapshot.children) {
val messageModel = dataModel.getValue(MessageModel::class.java)
val messageId = dataModel.key
if (messageModel != null) {
if (messageId != null) {
// readerUidMap을 업데이트
FirebaseRef.message.child(chatRoomId!!).child(messageId).child("readerUids")
.updateChildren(readerUidMap as Map<String, Boolean>)
.addOnCompleteListener { readerUidTask ->
if (readerUidTask.isSuccessful) {
// readerUid 업데이트가 성공한 경우 unreadUserCount를 계산하여 업데이트합니다.
val unreadUserCount = count.toInt() - messageModel.readerUids.size
FirebaseRef.message.child(chatRoomId!!).child(messageId).child("unreadUserCount")
.setValue(unreadUserCount)
} else {
Log.d("ChatRoomActivity", "reader UID를 업데이트하지 못함")
}
}
}
if (messageModel.senderUid != FirebaseAuthUtils.getUid()) {
messageModel.viewType = MessageModel.VIEW_TYPE_YOU
}
newMessages.add(messageModel)
}
}
messageList.addAll(newMessages)
messageAdapter.notifyDataSetChanged()
Log.d("MessageList", messageList.toString())
recyclerView.post {
recyclerView.scrollToPosition(recyclerView.adapter?.itemCount?.minus(1) ?: 0)
}
}
override fun onCancelled(databaseError: DatabaseError) {
Log.w("MyMessage", "onCancelled", databaseError.toException())
}
}
FirebaseRef.message.child(chatRoomId).addValueEventListener(postListener)
}
}
이제 코드를 실행해보면, 아래와 같이 읽지 않은 유저의 수가 메시지 옆에 표시될 것이다.