import { defineStore } from "pinia"; import { computed, ref, set } from "vue"; import { fetchAllBroadcasts } from "@/api/notifications.broadcast"; import type { components } from "@/api/schema"; import { useUserLocalStorage } from "@/composables/userLocalStorage"; import { mergeObjectListsById } from "@/utils/utils"; export type BroadcastNotification = components["schemas"]["BroadcastNotificationResponse"]; type Expirable = Pick; export const useBroadcastsStore = defineStore("broadcastsStore", () => { const broadcasts = ref([]); const loadingBroadcasts = ref(false); const dismissedBroadcasts = useUserLocalStorage<{ [key: string]: Expirable }>("dismissed-broadcasts", {}); const activeBroadcasts = computed(() => { return broadcasts.value.filter(isActive); }); async function loadBroadcasts() { loadingBroadcasts.value = true; await fetchAllBroadcasts() .then((data) => { broadcasts.value = mergeObjectListsById(data, [], "create_time", "desc"); }) .finally(() => { loadingBroadcasts.value = false; }); } function updateBroadcasts(broadcastList: BroadcastNotification[]) { broadcasts.value = mergeObjectListsById(broadcasts.value, broadcastList, "create_time", "desc").filter( (b) => !hasExpired(b.expiration_time), ); } function dismissBroadcast(broadcast: BroadcastNotification) { set(dismissedBroadcasts.value, broadcast.id, { expiration_time: broadcast.expiration_time }); } function hasExpired(expirationTimeStr?: string | null) { if (!expirationTimeStr) { return false; } const expirationTime = new Date(`${expirationTimeStr}Z`); const now = new Date(); return now > expirationTime; } function isActive(broadcast: BroadcastNotification) { return ( !dismissedBroadcasts.value[broadcast.id] && !hasExpired(broadcast.expiration_time) && hasBeenPublished(broadcast) ); } function hasBeenPublished(broadcast: BroadcastNotification) { const publicationTime = new Date(`${broadcast.publication_time}Z`); const now = new Date(); return now >= publicationTime; } function clearExpiredDismissedBroadcasts() { for (const key in dismissedBroadcasts.value) { if (hasExpired(dismissedBroadcasts.value[key]?.expiration_time)) { delete dismissedBroadcasts.value[key]; } } } clearExpiredDismissedBroadcasts(); return { broadcasts, dismissedBroadcasts, loadingBroadcasts, activeBroadcasts, dismissBroadcast, loadBroadcasts, updateBroadcasts, }; });