Prechádzať zdrojové kódy

refactor: Moves data fetching into WhatIsNew modal

Owen Diffey 1 rok pred
rodič
commit
4c3398e6ca

+ 1 - 1
backend/src/models/permissions/isDj.ts

@@ -1,2 +1,2 @@
 export default (model, user) =>
-	model && user && model.djs.contains(user._id.toString());
+	model && user && model.djs.includes(user._id.toString());

+ 1 - 1
backend/src/models/permissions/isOwner.ts

@@ -7,7 +7,7 @@ export default (model, user) => {
 	else if (model.schema.path("owner")) ownerAttribute = "owner";
 
 	if (ownerAttribute)
-		return model[ownerAttribute].toString() === user._id.toString();
+		return model[ownerAttribute]?.toString() === user._id.toString();
 
 	return false;
 };

+ 4 - 2
backend/src/models/schemas/news/config.ts

@@ -25,9 +25,11 @@ export default {
 		newest: {
 			async method(
 				context: JobContext,
-				payload?: { showToNewUsers: boolean }
+				payload?: { showToNewUsers?: boolean; limit?: number }
 			) {
-				return this.find().newest(payload?.showToNewUsers);
+				const query = this.find().newest(payload?.showToNewUsers);
+				if (payload?.limit) return query.limit(payload?.limit);
+				return query;
 			},
 			hasPermission: true
 		}

+ 1 - 44
frontend/src/App.vue

@@ -12,7 +12,6 @@ import { useUserPreferencesStore } from "@/stores/userPreferences";
 import { useModalsStore } from "@/stores/modals";
 import aw from "@/aw";
 import keyboardShortcuts from "@/keyboardShortcuts";
-import { useNewsModelStore } from "./stores/models/news";
 
 const ModalManager = defineAsyncComponent(
 	() => import("@/components/ModalManager.vue")
@@ -32,7 +31,6 @@ const configStore = useConfigStore();
 const userAuthStore = useUserAuthStore();
 const userPreferencesStore = useUserPreferencesStore();
 const modalsStore = useModalsStore();
-const { newest } = useNewsModelStore();
 
 const socketConnected = ref(true);
 const keyIsDown = ref("");
@@ -196,48 +194,7 @@ onMounted(async () => {
 			}
 		);
 
-		const newUser = !localStorage.getItem("firstVisited");
-		newest(newUser).then(data => {
-			const [news] = data;
-
-			if (news) {
-				if (newUser) {
-					openModal({ modal: "whatIsNew", props: { news } });
-				} else if (localStorage.getItem("whatIsNew")) {
-					if (
-						parseInt(localStorage.getItem("whatIsNew") as string) <
-						news.createdAt
-					) {
-						openModal({
-							modal: "whatIsNew",
-							props: { news }
-						});
-						localStorage.setItem(
-							"whatIsNew",
-							news.createdAt.toString()
-						);
-					}
-				} else {
-					if (
-						localStorage.getItem("firstVisited") &&
-						parseInt(
-							localStorage.getItem("firstVisited") as string
-						) < news.createdAt
-					)
-						openModal({
-							modal: "whatIsNew",
-							props: { news }
-						});
-					localStorage.setItem(
-						"whatIsNew",
-						news.createdAt.toString()
-					);
-				}
-			}
-
-			if (!localStorage.getItem("firstVisited"))
-				localStorage.setItem("firstVisited", Date.now().toString());
-		});
+		openModal("whatIsNew");
 
 		router.isReady().then(() => {
 			if (

+ 1 - 1
frontend/src/components/modals/EditNews.vue

@@ -121,7 +121,7 @@ onMounted(async () => {
 
 			if (!data) return;
 
-			const [model] = await registerModels(newsStore, [data]);
+			const [model] = await registerModels(newsStore, data);
 
 			setModelValues(model, ["markdown", "status", "showToNewUsers"]);
 

+ 46 - 5
frontend/src/components/modals/WhatIsNew.vue

@@ -1,8 +1,11 @@
 <script setup lang="ts">
-import { defineAsyncComponent, onMounted } from "vue";
+import { defineAsyncComponent, onMounted, ref } from "vue";
 import { formatDistance } from "date-fns";
 import { marked } from "marked";
 import dompurify from "dompurify";
+import { useNewsModelStore } from "@/stores/models/news";
+import { useModels } from "@/composables/useModels";
+import { useModalsStore } from "@/stores/modals";
 
 const Modal = defineAsyncComponent(() => import("@/components/Modal.vue"));
 const UserLink = defineAsyncComponent(
@@ -10,11 +13,49 @@ const UserLink = defineAsyncComponent(
 );
 
 defineProps({
-	modalUuid: { type: String, required: true },
-	news: { type: Object, required: true }
+	modalUuid: { type: String, required: true }
 });
 
-onMounted(() => {
+const { registerModels, onDeleted } = useModels();
+
+const newsStore = useNewsModelStore();
+
+const { closeCurrentModal } = useModalsStore();
+
+const news = ref();
+
+onMounted(async () => {
+	let firstVisited = localStorage.getItem("firstVisited");
+
+	const newUser = !firstVisited;
+
+	const [model] = await newsStore.newest(newUser, 1);
+
+	if (model && newUser) {
+		firstVisited = Date.now().toString();
+
+		localStorage.setItem("firstVisited", firstVisited);
+	} else if (
+		!model ||
+		(localStorage.getItem("whatIsNew") &&
+			parseInt(localStorage.getItem("whatIsNew") as string) >=
+				Date.parse(model.createdAt)) ||
+		parseInt(firstVisited as string) >= model.createdAt
+	) {
+		closeCurrentModal(true);
+		return;
+	}
+
+	localStorage.setItem("whatIsNew", Date.parse(model.createdAt).toString());
+
+	const [_model] = await registerModels(newsStore, model);
+
+	news.value = _model;
+
+	await onDeleted(newsStore, ({ oldDoc }) => {
+		if (oldDoc._id === news.value?._id) closeCurrentModal(true);
+	});
+
 	marked.use({
 		renderer: {
 			table(header, body) {
@@ -31,7 +72,7 @@ const { sanitize } = dompurify;
 </script>
 
 <template>
-	<modal title="News" class="what-is-news-modal">
+	<modal v-if="news" title="News" class="what-is-news-modal">
 		<template #body>
 			<div
 				class="section news-item"

+ 1 - 3
frontend/src/stores/models/model.ts

@@ -221,9 +221,7 @@ export const createModelStore = modelName => {
 
 		if (existingModel) return existingModel;
 
-		const data = await runJob(`data.${modelName}.findById`, { _id });
-
-		const [model] = await registerModels(data);
+		const [model] = await runJob(`data.${modelName}.findById`, { _id });
 
 		return model;
 	};

+ 2 - 5
frontend/src/stores/models/news.ts

@@ -9,11 +9,8 @@ export const useNewsModelStore = defineStore("newsModel", () => {
 
 	const published = async () => runJob("data.news.published", {});
 
-	const newest = async (showToNewUsers?) => {
-		const data = await runJob("data.news.newest", { showToNewUsers });
-
-		return modelStore.registerModels(data);
-	};
+	const newest = async (showToNewUsers?, limit?) =>
+		runJob("data.news.newest", { showToNewUsers, limit });
 
 	return {
 		...modelStore,