浏览代码

refactor: use new published/unpublished events on news page, sort news based on createdAt date

Kristian Vos 8 月之前
父节点
当前提交
3084b446cb
共有 1 个文件被更改,包括 36 次插入18 次删除
  1. 36 18
      frontend/src/pages/News.vue

+ 36 - 18
frontend/src/pages/News.vue

@@ -1,10 +1,11 @@
 <script setup lang="ts">
-import { defineAsyncComponent, ref, onMounted } from "vue";
+import { defineAsyncComponent, ref, onMounted, computed } from "vue";
 
 import { formatDistance } from "date-fns";
 import { marked } from "marked";
 import DOMPurify from "dompurify";
 import { NewsModel } from "@musare_types/models/News";
+import { forEachIn } from "@common/utils/forEachIn";
 import { useEvents } from "@/composables/useEvents";
 import { useModels } from "@/composables/useModels";
 import { useWebsocketStore } from "@/stores/websocket";
@@ -17,11 +18,19 @@ const MainFooter = defineAsyncComponent(
 );
 
 const { runJob } = useWebsocketStore();
-const { onReady } = useEvents();
-const { registerModel, registerModels, onCreated, onDeleted } = useModels();
+const { onReady, subscribe } = useEvents();
+const { registerModel, registerModels } = useModels();
 
 const news = ref<NewsModel[]>([]);
 
+const sortedNews = computed(() =>
+	news.value.toSorted(
+		(newsA, newsB) =>
+			new Date(newsB.createdAt).getTime() -
+			new Date(newsA.createdAt).getTime()
+	)
+);
+
 const { sanitize } = DOMPurify;
 
 onMounted(async () => {
@@ -36,24 +45,33 @@ onMounted(async () => {
 		}
 	});
 
-	await onReady(async () => {
-		news.value = await registerModels(
-			await runJob("data.news.newest", {}),
-			{ news: "createdBy" }
-		);
-	});
+	const addNews = async models => {
+		await forEachIn(models, async model => {
+			await subscribe(
+				`data.news.unpublished:${model._id}`,
+				async ({ oldDoc }) => {
+					const index = news.value.findIndex(
+						doc => doc._id === oldDoc._id
+					);
 
-	await onCreated("news", async ({ doc }) => {
-		const newDoc = await registerModel(doc, { news: "createdBy" });
-		news.value.unshift(newDoc);
-	});
+					if (index < 0) return;
 
-	await onDeleted("news", async ({ oldDoc }) => {
-		const index = news.value.findIndex(doc => doc._id === oldDoc._id);
+					news.value.splice(index, 1);
+				}
+			);
+			news.value.push(model);
+		});
+	};
 
-		if (index < 0) return;
+	await onReady(async () => {
+		const docs = await runJob("data.news.newest", {});
+		const models = await registerModels(docs, { news: "createdBy" });
+		await addNews(models);
+	});
 
-		news.value.splice(index, 1);
+	await subscribe("data.news.published", async ({ doc }) => {
+		const model = await registerModel(doc, { news: "createdBy" });
+		await addNews([model]);
 	});
 });
 </script>
@@ -66,7 +84,7 @@ onMounted(async () => {
 			<div class="content-wrapper">
 				<h1 class="has-text-centered page-title">News</h1>
 				<div
-					v-for="item in news"
+					v-for="item in sortedNews"
 					:key="item._id"
 					class="section news-item"
 				>