(가) 렌더링되는 리스트들의 메세지 데이터에 접근한다
chatroom
컬렉션에서 리스트의 채팅방 데이터 > messages
컬렉션 내 데이터 접근.
(나) (가)에서 내가 보낸 메세지만 추려낸다
uid가 내 아이디인 것 개수 세기
(다)에서 read
필드 값이 false
인 것을 찾는다
전역
// 전역변수 선언 영역
var chatroomID;
var productRef = db.collection('product');
var chatroomRef = db.collection('chatroom');
// var chatMsgRef = db.collection('chatroom');
var tempListNull = `<p class="text-center text-secondary">아직 대화중인 채팅방이 없어요</p>`;
// 함수 호출 영역
findMychatList();
[ 함수: getProduct ] 채팅방 데이터 정보로 product정보 불러온다 > dom 바인딩
function getProduct(a, productID) {
productRef
.doc(a.data().productID)
.get()
.then((res) => {
console.log('작성자: ', res.data().uid);
console.log(res.data().content);
const authorUID = res.data().uid;
const productData = res.data();
// DOM
$('#chat-list').append(
`
<a href=/page/chat-detail.html?id=${productID}>
<li class="row border-bottom py-1 px-2 align-items-center chatbox">
<div class="col-2 px-auto">
<img src="${productData.image}" class="chat-product-thumb product-img">
</div>
<div class="col-9 my-auto ps-0">
<div class="hstack">
<p class="m-0 fw-semibold username">${productData.username}</p>
<p class="m-0 text-black-50"><small>∙</small></p>
<p class="m-0 text-black-50" id="chat-date"><small></small></p>
</div>
<p class="m-0" id="chat-msg">${productData.username}님과 대화가 시작되었어요</p>
</div>
<div class="col-1 text-end my-auto">
<div class="chat-badge unread-box">
<p class="chat-badge-tx unread">22</p>
</div>
</div>
</li>
<a>
`
);
});
}
[ 함수: findMychatList ] 채팅방 DB서 로그인 유저 UID 포함된 리스트 모두 찾는다
function findMychatList() {
chatroomRef
.where('who', 'array-contains', myUID)
.get()
.then((result) => {
console.log(result.size);
createList(result);
});
}
[ 함수: createList ] 채팅방 리스트 생성 (findChatList 결과값 받아서)
function createList(a) {
// 1) 채팅방 목록 없을 경우
if (a.size == 0) {
console.log('개설된 채팅방 X');
// $('#chat-list').append(tempListNull);
$('#empty').removeClass('d-none');
}
// 2) 채팅방 목록 있을 경우
else {
a.forEach((doc) => {
const productID = doc.id;
const who = doc.data().who;
const you = findYouinChatroom(who);
// 바인딩 함수
getProduct(doc, productID);
getLastChatMsg(productID);
countUnReadMsg(productID, you).then((res) => {
if (res == 0) {
console.log('모두 읽음');
$('.unread-box').last().addClass('invisible');
} else {
console.log('아직안읽음 :', res);
// $('.unread').first().text(res);
$('.unread').last().text(res);
}
});
// let unreadtx = $('.unread').last();
// console.log('unreadtx: ', unreadtx);
});
}
}
[ findYouinChatroom : 참여자 배열로 받아 상대방 UID 찾아냄 ]
function findYouinChatroom(part) {
var res;
part.map((a) => {
if (a != myUID) {
// console.log('상대:', a);
res = a;
}
});
return res;
}
[함수 : countUnReadMsg] 내 메세지 찾는다
var countUnReadMsg = (params, paramYou) =>
new Promise(function (resolve) {
var resReturn;
console.log(params);
// console.log(authorUID);
console.log(myUID);
chatroomRef
.doc(params)
.collection('messages')
.where('uid', '==', paramYou)
.where('read', '==', false)
.get()
.then((res) => {
console.log('읽지않은 상대 메세지 개수 :', res.size);
// 읽지않은 메세지 수 반환
resReturn = res.size;
console.log('resReturn:', resReturn);
resolve(resReturn);
});
});
'내 UID가 아닌 것' 명령 줄 때 !=
사용하려 했으나
복합쿼리(where
)를 연달아 사용할 때, '!=' 연산자는 사용 못함. (할 수 있더라도 DB에 사전 작업 해두어야 함)
해결
이전 체이닝된 함수에서 상대 UID알아내어 이 함수에 전달한다.
읽음 여부 해당 채팅 메세지 도큐먼트 내의 read
필드에 저장, 기본값 false
.
해당 메세지 가져오면 true
로 변경. (읽은 유저가 본인일 경우에는 제외)
메세지 생성 함수. 여기서 메세지 발신 주체 구분한다
function createDOM() {
db.collection('chatroom')
.doc(chatroomID)
.collection('messages')
.orderBy('date')
.onSnapshot((doc) => {
// DB 데이터로 DOM 생성하기 전에 내용 비워준다.
$('#wrap').html('');
doc.forEach((a) => {
let datejs = dayjs(a.data().date.toDate());
var temp = `
<li class="d-flex flex-row-reverse align-items-end my-3">
<span class="chat-box mine ms-1">${a.data().content}</span>
<span class="tx-small text-end">
${datejs.format('M월D일 HH:mm')}
</span>
</li>
`;
if (a.data().uid == myUID) {
console.log('내메세지');
$('#wrap').append(temp);
} else {
console.log('상대메세지');
console.log('메세지 id', a.id);
changeRead(a);
$('img').attr('src', '');
$('#wrap').append(`
<li class="d-flex flex-row align-items-end my-3">
<img src=""/>
</div>
<span class="chat-box me-1">${a.data().content}</span>
<span class="tx-small">
${datejs.format('M월D일 HH:mm')}
</span>
</li>
`);
}
});
// DOM 생성완료 후 스크롤을 최하단으로 내린다
scrollBottom();
});
}
메세지 발신 주체 따라 읽음 처리하는 함수
function changeRead(params) {
chatroomRef
.doc(chatroomID)
.collection('messages')
.doc(params.id)
.update({ read: true })
.then(() => {
console.log('읽음 updated');
});
}
읽음 여부 따라 1 UI 다르게 처리 한다
doc.forEach((a) => {
let datejs = dayjs(a.data().date.toDate());
var temp = `
<li class="d-flex flex-row-reverse align-items-end my-3">
<span class="chat-box mine ms-1">${a.data().content}</span>
<div>
<p class="text-danger fw-semibold text-end mb-0 read"
style="font-size: .8rem; line-height: 0;">1</p>
<span class="tx-small text-end">
${datejs.format('M월D일 HH:mm')}
</span>
</div>
</li>
`;
if (a.data().uid == myUID) {
console.log('내메세지');
$('#wrap').append(temp);
if (a.data().read == true) {
console.log('읽음');
$('.read').addClass('d-none');
}
} else {
console.log('상대메세지');
console.log('메세지 id', a.id);
changeRead(a);
$('img').attr('src', '');
$('#wrap').append(`
<li class="d-flex flex-row align-items-end my-3">
<img src=""/>
</div>
<span class="chat-box me-1">${a.data().content}</span>
<span class="tx-small">
${datejs.format('M월D일 HH:mm')}
</span>
</li>
`);
}
});
// DOM 생성완료 후 스크롤을 최하단으로 내린다
scrollBottom();
});
}