diff --git a/src/routes/(console)/project-[project]/messaging/+page.svelte b/src/routes/(console)/project-[project]/messaging/+page.svelte index efac29adc..5d518d5c8 100644 --- a/src/routes/(console)/project-[project]/messaging/+page.svelte +++ b/src/routes/(console)/project-[project]/messaging/+page.svelte @@ -43,6 +43,8 @@ import type { Column } from '$lib/helpers/types'; import { writable } from 'svelte/store'; import { canWriteMessages } from '$lib/stores/roles'; + import { onDestroy, onMount } from 'svelte'; + import { stopPolling, pollMessagesStatus } from './helper'; export let data: PageData; let selected: string[] = []; @@ -90,6 +92,16 @@ showDelete = false; } } + + onMount(() => { + const processingMessages = data.messages.messages.filter( + (message) => message.status === 'processing' + ); + + pollMessagesStatus(processingMessages); + }); + + onDestroy(stopPolling); diff --git a/src/routes/(console)/project-[project]/messaging/helper.ts b/src/routes/(console)/project-[project]/messaging/helper.ts new file mode 100644 index 000000000..389778e14 --- /dev/null +++ b/src/routes/(console)/project-[project]/messaging/helper.ts @@ -0,0 +1,43 @@ +import { sdk } from '$lib/stores/sdk'; +import { type Models } from '@appwrite.io/console'; + +/** Stores active polling intervals for messages. */ +const messageIntervals = new Map>(); + +/** Checks the status of a message and stops polling if it's no longer processing. */ +function checkMessageStatus(message: Models.Message) { + sdk.forProject.messaging + .getMessage(message.$id) + .then((msg) => { + if (msg.status !== 'processing') { + clearPolling(message.$id); + message.status = msg.status; + } + }) + .catch(() => clearPolling(message.$id)); +} + +/** Clears polling for a specific message. */ +function clearPolling(messageId: string) { + const intervalID = messageIntervals.get(messageId); + if (intervalID) { + clearInterval(intervalID); + messageIntervals.delete(messageId); + } +} + +/** Stops polling for all messages. */ +export function stopPolling() { + messageIntervals.forEach((_, messageId) => clearPolling(messageId)); +} + +/** Starts polling message statuses. */ +export function pollMessagesStatus(messages: Models.Message[]) { + messages.forEach((message) => { + clearPolling(message.$id); + checkMessageStatus(message); + + const intervalID = setInterval(() => checkMessageStatus(message), 2000); + messageIntervals.set(message.$id, intervalID); + }); +} diff --git a/src/routes/(console)/project-[project]/messaging/message-[message]/overview.svelte b/src/routes/(console)/project-[project]/messaging/message-[message]/overview.svelte index c9bbe244f..f5acb4713 100644 --- a/src/routes/(console)/project-[project]/messaging/message-[message]/overview.svelte +++ b/src/routes/(console)/project-[project]/messaging/message-[message]/overview.svelte @@ -9,6 +9,8 @@ import SendModal from './sendModal.svelte'; import ScheduleModal from './scheduleModal.svelte'; import CancelModal from './cancelModal.svelte'; + import { onDestroy, onMount } from 'svelte'; + import { stopPolling, pollMessagesStatus } from '../helper'; export let message: Models.Message & { data: Record }; export let topics: Models.Topic[]; @@ -18,6 +20,14 @@ let showCancel = false; let showFailed = false; let errors: string[] = []; + + onDestroy(stopPolling); + + onMount(() => { + if (message.status === 'processing') { + pollMessagesStatus([message]); + } + }); @@ -70,7 +80,11 @@ - + pollMessagesStatus([message])} /> diff --git a/src/routes/(console)/project-[project]/messaging/message-[message]/sendModal.svelte b/src/routes/(console)/project-[project]/messaging/message-[message]/sendModal.svelte index fdfaa1d5c..c9b799d79 100644 --- a/src/routes/(console)/project-[project]/messaging/message-[message]/sendModal.svelte +++ b/src/routes/(console)/project-[project]/messaging/message-[message]/sendModal.svelte @@ -7,12 +7,14 @@ import { Submit, trackEvent, trackError } from '$lib/actions/analytics'; import { MessagingProviderType, type Models } from '@appwrite.io/console'; import { Dependencies } from '$lib/constants'; + import { createEventDispatcher } from 'svelte'; export let show = false; export let message: Models.Message & { data: Record }; export let topics: Models.Topic[]; - let totalTargets = message.targets?.length ?? 0; + const dispatch = createEventDispatcher(); + $: totalTargets = message.targets?.length ?? 0; for (const topic of topics) { if (message.providerType == MessagingProviderType.Push) { @@ -80,6 +82,8 @@ type: 'error' }); trackError(error, Submit.MessagingMessageUpdate); + } finally { + dispatch('update'); } }; diff --git a/src/routes/(console)/project-[project]/messaging/message-[message]/updateTopics.svelte b/src/routes/(console)/project-[project]/messaging/message-[message]/updateTopics.svelte index be240b2d1..3d89ccccf 100644 --- a/src/routes/(console)/project-[project]/messaging/message-[message]/updateTopics.svelte +++ b/src/routes/(console)/project-[project]/messaging/message-[message]/updateTopics.svelte @@ -83,7 +83,7 @@
- + Topics {@const sum = topicIds.length} @@ -92,7 +92,7 @@
Topic
- {#if message.status == 'draft'} + {#if message.status === 'draft'}