🔥 안 읽은 메시지가 있는 채팅방을 상단으로 정렬하기
안 읽은 메시지가 많은 채팅방을 상단으로 정렬하면
채팅방이 아래에 있는 경우 메시지가 있는지 여부를 확인하지 못하여
오랫동안 메시지를 읽지 않고 방치하는 것을 방지할 수 있습니다.
1. Store에서 채팅방 정렬 로직 추가
📌 store/chatStore.js 수정
import { defineStore } from "pinia";
import { getDatabase, ref, onValue } from "firebase/database";
import { auth } from "@/firebase";
export const useChatStore = defineStore("chat", {
state: () => ({
chatRooms: [], // 채팅방 목록
unreadCounts: {}, // 채팅방별 안 읽은 메시지 개수
}),
actions: {
// ✅ 채팅방 목록 가져오기
fetchChatRooms() {
const db = getDatabase();
const user = auth.currentUser;
if (!user) return;
const chatRoomsRef = ref(db, `users/${user.uid}/chatRooms`);
onValue(chatRoomsRef, (snapshot) => {
if (snapshot.exists()) {
this.chatRooms = Object.entries(snapshot.val()).map(([id, room]) => ({
id,
...room,
}));
this.listenForUnreadMessages();
}
});
},
// ✅ 안 읽은 메시지 개수 업데이트
listenForUnreadMessages() {
const db = getDatabase();
const user = auth.currentUser;
if (!user) return;
this.chatRooms.forEach((room) => {
const messagesRef = ref(db, `messages/${room.id}`);
onValue(messagesRef, (snapshot) => {
if (snapshot.exists()) {
const unreadMessages = Object.values(snapshot.val()).filter(
(msg) => msg.receiver === user.uid && msg.status === "unread"
);
this.unreadCounts[room.id] = unreadMessages.length;
} else {
this.unreadCounts[room.id] = 0;
}
});
});
},
},
getters: {
// ✅ 채팅방을 안 읽은 메시지가 많은 순서로 정렬
sortedChatRooms: (state) => {
return [...state.chatRooms].sort((a, b) => {
const unreadA = state.unreadCounts[a.id] || 0;
const unreadB = state.unreadCounts[b.id] || 0;
return unreadB - unreadA; // 안 읽은 메시지가 많은 순으로 정렬
});
},
},
});
✔ sortedChatRooms 안 읽은 메시지 개수를 기준으로 정렬
✔ 안 읽은 메시지가 많을수록 상단에 배치
2. UI에서 정렬된 채팅방 표시
📌 ChatList.vue 수정
<script setup>
import { useChatStore } from "@/store/chatStore";
import { onMounted } from "vue";
const chatStore = useChatStore();
onMounted(() => {
chatStore.fetchChatRooms();
});
</script>
<template>
<v-list>
<v-list-item
v-for="chatRoom in chatStore.sortedChatRooms"
:key="chatRoom.id"
:to="`/chat/${chatRoom.id}`"
>
<v-list-item-content>
<v-list-item-title>{{ chatRoom.name }}</v-list-item-title>
</v-list-item-content>
<!-- ✅ 안 읽은 메시지가 있으면 배지 표시 -->
<v-badge
v-if="chatStore.unreadCounts[chatRoom.id] > 0"
:content="chatStore.unreadCounts[chatRoom.id]"
color="red"
>
<v-icon>mdi-message</v-icon>
</v-badge>
</v-list-item>
</v-list>
</template>
✔ 정렬된 채팅방 목록을 sortedChatRooms로 렌더링
✔ 안 읽은 메시지가 많은 채팅방이 자동으로 상단에 배치
🎯 결론
✅ 채팅방을 안 읽은 메시지 개수를 기준으로 정렬
✅ 안 읽은 메시지가 많을수록 상단에 배치
✅ 새 메시지가 오면 자동으로 정렬 업데이트 🚀
'Vue3, Firebase 프로젝트 - 채팅앱 VSignal' 카테고리의 다른 글
17. Vue3 Firebase 프로젝트 채팅앱 VSignal - 마지막 메시지 시간 표시 및 정렬 (0) | 2025.03.28 |
---|---|
16. Vue3 Firebase 프로젝트 채팅앱 VSignal - 채팅방 마지막 메시지 미리보기 (0) | 2025.03.27 |
14. Vue3 Firebase 프로젝트 채팅앱 VSignal - 안 읽은 메시지 개수 배지 추가하기 (0) | 2025.03.25 |
13. Vue3 Firebase 프로젝트 채팅앱 VSignal - 메시지를 언제 읽었는지 표시하기 (0) | 2025.03.24 |
12. Vue3 Firebase 프로젝트 채팅앱 VSignal - 실시간 메시지 읽음 확인 (0) | 2025.03.23 |