Vue로 PWA 개발 - 그랜파 개발자
Vue 프로젝트 Beta Test : mylog, 일상의 기록
개발이 진행됨에 따라 소스 코드를 계속 추가해 갑니다.
mylog 구독
마이로그 상세보기에 구독 버튼이 있습니다. 구독 중이 아니면 ‘구독’, 구독 중이면 ‘구독 취소’로 나타납니다. 구독을 하게 되면 내가 구독중인 마이로그를 ‘구독’ 페이지에서 모아볼 수 있습니다.
1. 구독 신청
구독 버튼을 toggle 버튼입니다. 같은 버튼으로 구독 또는 구독 취소를 할 수 있습니다. 구독은 마이로그 상세 보기에서 구독 버튼을 눌러 구독 신청을 하지만 마이로그 하나에 대한 구독이 아니라 글쓴이에 대한 구독입니다.
구독 정보는 subscriptions 컬렉션에 저장됩니다. subscriptions 컬렉션은 userId(회원입니다.), authorId(글쓴이입니다), 그리고 생성일이 저장됩니다. 그러므로 구독 여부는 subscriptions에서 userId로 authorId가 있는지 확인해서 있으면 구독중, 없으면 아직 구독하지 않은 상태입니다. 이를 이용하여 구독 버튼에 ‘구독’ 또는 ‘구독취소’를 나타냅니다.
1-1. 구독 여부 확인
async checkSubscription({ commit }, { userId, authorId }) {
commit('setLoading', true);
const q = query(
collection(db, "subscriptions"),
where("userId", "==", userId),
where("authorId", "==", authorId)
);
const querySnapshot = await getDocs(q);
if (!querySnapshot.empty) {
commit("setSubscribed", true);
commit("setSubscriptionId", querySnapshot.docs[0].id); // Get the Firestore document ID for the subscription
} else {
commit("setSubscribed", false);
commit("setSubscriptionId", '');
}
commit('setLoading', false);
},
1-2. 구독 신청
버튼의 이름이 ‘구독’이면 아직 구독 중이 아니므로 버튼을 누르면 subscriptions 컬렉션에 구독 정보를 저장한다.
async subscribeToUser({ commit, dispatch }, {userId, authorId}) {
commit('setLoading', true);
try {
const subscriptionRef = collection(db, "subscriptions");
await addDoc(subscriptionRef, {
userId: userId,
authorId: authorId,
createdAt: new Date(),
});
dispatch("fetchUserSubscriptions", userId);
} catch (error) {
commit("setError", error);
console.error("Error subscribing:", error);
}
commit('setLoading', false);
},
1-3. 구독 취소
버튼 이름이 ‘구독 취소’이면 현재 구독 중이므로 버튼을 누르면 subscriptions 컬렉션에 구독 정보를 삭제하여 구독을 취소합니다.
async unsubscribeFromUser({ commit, dispatch }, {userId, subscriptionId}) {
commit('setLoading', true);
try {
const subscriptionDocRef = doc(db, "subscriptions", subscriptionId);
await deleteDoc(subscriptionDocRef);
dispatch("fetchUserSubscriptions", userId);
} catch (error) {
//commit("setError", error);
alert("Error unsubscribing : ", error.message);
}
commit('setLoading', false);
},
2. 구독 보기
SubscribedPosts.vue
<!-- src/viewss/SubscribedPosts.vue -->
<template>
<v-container>
. . .
<v-row v-if="subscribedMylogs.length > 0">
<!-- 구독 마이로그 리스트-->
<v-col v-for="mylog in subscribedMylogs" :key="mylog.id" @click="viewMylog(mylog.id)" cols="12">
<v-card>
<!-- 마이로그 제목 -->
<v-card-title style="font-size:1em">{{ mylog.title }}</v-card-title>
<!-- 안전한 HTML로 변경한 마이로그 내용-->
<!-- eslint-disable -->
<v-card-text style="font-size:1em" class="mt-n2 mb-n6" v-html="sanitizeContent(mylog.content)"></v-card-text>
<!-- eslint-enable -->
<!-- 댓글의 개수, 생성일 -->
<v-card-subtitle>
<span v-if="mylog.commentCount> 0" style="cursor: pointer">댓글 {{mylog.commentCount }} </span>
{{ mylog.userName }} . {{ formatDate(mylog.createdAt) }}
<!--조회수가 있을 경우에만 나타냄 -->
<span v-if="mylog.views > 0" > ({{ mylog.views }})</span>
</v-card-subtitle>
</v-card>
</v-col>
</v-row>
. . .
</v-container>
</template>
<script>
import { mapActions, mapGetters } from "vuex";
import sanitizeHtml from 'sanitize-html';
export default {
. . .
async created() {
// 회원의 구독 중인 마이로그를 로드한다.
this.user = this.$store.state.auth.user;
this.fetchSubscribedMylogs(this.user.id);
},
. . .
methods: {
...mapActions('mylogs', ['fetchSubscribedMylogs']),
. . .
};
</script>
store - mylogs.js
// src/store/modules/mylogs.js
import { v4 as uuidv4 } from 'uuid';
import { db, doc, collection, getDoc, getDocs, setDoc, addDoc,updateDoc, deleteDoc, arrayUnion, increment, where } from "@/firebase";
import { query, orderBy } from "@/firebase";
const state = {
. . .
subscribedMylogs: [], // 구독 마이로그 목록
. . .
};
const mutations = {
. . .
setSubscribedMylogs(state, subscribedMylogs) { // 구독 마이로그 목록
state.subscribedMylogs = subscribedMylogs;
},
. . .
};
const actions = {
. . .
// 구독 중인 마이로그 로드
async fetchSubscribedMylogs({ commit }, userId) {
commit('setLoading', true);
// 구독 목록
const authodIds = [];
const q = query(collection(db, "subscriptions"), where("userId", "==", userId));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
authodIds.push(doc.data().authorId);
});
// 구독 마이로그 목록
if(authodIds.length>0) {
let subscribedMylogs = [];
const mylogQ = query(collection(db, "mylogs"), where("userId", "in", authodIds));
const mylogsSnapshot = await getDocs(mylogQ);
subscribedMylogs = mylogsSnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
// 구독 마이로그 목록을 상태에 저장
commit("setSubscribedMylogs", subscribedMylogs);
}
commit('setLoading', false);
},
};
const getters = {
. . .
subscribedMylogs: state => state.subscribedMylogs, // 구독 마이로그 목록
. . .
};
export default {
namespaced: true,
state,
mutations,
actions,
getters
};
Vue PWA 프로젝트, mylog 코드
'Vue PWA mylog' 카테고리의 다른 글
mylog 내것 (0) | 2024.11.21 |
---|---|
mylog 쓰기 (0) | 2024.11.20 |
mylog 댓글, 답글 (2) | 2024.11.17 |
mylog 모아보기 (0) | 2024.11.16 |
mylog 조회수 (1) | 2024.11.15 |