From 5d436770130177aec7a6a236768a66e02bab6f1b Mon Sep 17 00:00:00 2001 From: dexagod Date: Fri, 25 Sep 2020 12:58:39 +0200 Subject: [PATCH] Fixed refresh issue for marriage proposal view. Added polling for notification and marriage proposal overview --- src/Components/MarriageRequestComponent.js | 1 - src/Components/MarriageViewComponent.js | 65 +++++++++++-------- .../NotificationsViewerComponent.js | 2 +- src/hooks/useNotifications.js | 45 ++++++++----- src/util/MarriageController.js | 4 +- src/util/notifications.js | 17 +++-- 6 files changed, 83 insertions(+), 51 deletions(-) diff --git a/src/Components/MarriageRequestComponent.js b/src/Components/MarriageRequestComponent.js index 169031d..83efc25 100644 --- a/src/Components/MarriageRequestComponent.js +++ b/src/Components/MarriageRequestComponent.js @@ -68,7 +68,6 @@ const MarriageRequestComponent = (props) => { const validateSubmission = async () => { for (let person of state){ - console.log("person", person) if (!person.webId) { window.alert(person.webId + 'is not a valid webId'); return false diff --git a/src/Components/MarriageViewComponent.js b/src/Components/MarriageViewComponent.js index 3eb706c..3bc4249 100644 --- a/src/Components/MarriageViewComponent.js +++ b/src/Components/MarriageViewComponent.js @@ -23,46 +23,60 @@ const INVITATIONREFUSED = ns.demo('refused') const MarriageViewComponent = (props) => { let allcontacts = props.contract.spouse.map(e => { e.type='spouse'; return e}) allcontacts = allcontacts.concat(props.contract.witness.map(e => { e.type='witness'; return e})) - const [contacts, setContacts] = useState(allcontacts.map(e => e.accepted=false)) + allcontacts = allcontacts.map(e => { e['status'] = e['status'] || 'pending' ; return e}) + const [contacts, setContacts] = useState(allcontacts) useEffect(() => { let mounted = true - async function getContactStatus(contactWebId){ - let accepted, refused; - for await (const acceptedEvent of data[contactWebId][INVITATIONACCEPTED]){ - if (`${await acceptedEvent}` === props.contract.id) accepted = true; - } - for await (const refusedEvent of data[contactWebId][INVITATIONREFUSED]){ - if (`${await refusedEvent}` === props.contract.id) refused = true; - } - return accepted ? 'accepted' : (refused ? 'refused' : 'pending') + async function refreshContacts() { + updateContacts(allcontacts).then(updatedContacts => { + if(mounted) setContacts(updatedContacts) + }) } - async function updateStatus() { - for (let contact of allcontacts){ - contact['status'] = await getContactStatus(contact.id) - } - if(mounted) setContacts(allcontacts) - } - updateStatus() + refreshContacts() + var interval = setInterval(() => { + refreshContacts() + }, 7000); return () => { mounted = false; + clearInterval(interval); } }, [props.contract]) - function accept() { - acceptProposal(props.webId, props.contract.id, props.contract.creator) + async function getContactStatus(contactWebId){ + let accepted, refused; + data.clearCache() + for await (const acceptedEvent of data[contactWebId][INVITATIONACCEPTED]){ + if (`${await acceptedEvent}` === props.contract.id) accepted = true; + } + for await (const refusedEvent of data[contactWebId][INVITATIONREFUSED]){ + if (`${await refusedEvent}` === props.contract.id) refused = true; + } + return accepted ? 'accepted' : (refused ? 'refused' : 'pending') + } + + async function updateContacts(contactsToUpdate) { + const contacts = [] + for (let contact of contactsToUpdate){ + contact['status'] = await getContactStatus(contact.id) + contacts.push(contact) + } + return contacts + } + + async function accept() { + await acceptProposal(props.webId, props.contract.id, props.contract.creator) resetView() } - function refuse() { - acceptProposal(props.webId, props.contract.id, props.contract.creator) + async function refuse() { + await acceptProposal(props.webId, props.contract.id, props.contract.creator) resetView() } - function resetView() { - const view = availableViews.marriageview - view.args = {contract: props.contract} - props.setview(view) + async function resetView() { + const updatedContacts = await updateContacts(contacts) + setContacts(updatedContacts) } function getContactButton(contact){ @@ -84,7 +98,6 @@ const MarriageViewComponent = (props) => { } return } - return (

Marriage Proposal

diff --git a/src/Components/NotificationsViewerComponent.js b/src/Components/NotificationsViewerComponent.js index a9bb8a2..6e6ec4b 100644 --- a/src/Components/NotificationsViewerComponent.js +++ b/src/Components/NotificationsViewerComponent.js @@ -23,7 +23,7 @@ const NotificationsViewerComponent = (props) => {

Notifications


{notifications.map(notification => { - return ( ) + return ( ) })}
diff --git a/src/hooks/useNotifications.js b/src/hooks/useNotifications.js index 9d321e2..7cfa977 100644 --- a/src/hooks/useNotifications.js +++ b/src/hooks/useNotifications.js @@ -1,27 +1,40 @@ import { useState, useEffect } from 'react'; -import { getNotificationMetadata, getNotification } from '../util/notifications'; +import { getNotificationMetadata, getNotification, checkNewNotifications } from '../util/notifications'; const useNotifications = function(webId) { const [notifications, setNotifications] = useState([]); + useEffect(() => { - let mounted = true - async function fetchNotifications(webId){ - const notificationsMetadata = await getNotificationMetadata(webId) - if(!notificationsMetadata) return [] - const notificationList = [] - for await (const metadata of notificationsMetadata){ - const notification = await getNotification(metadata.id) - notification.metadata = metadata - notificationList.push(notification) - } - if(mounted) setNotifications(notificationList) - } - if(webId) fetchNotifications(webId) + updateNotifications(webId, notifications) + const interval = setInterval(() => { + updateNotifications(webId, notifications) + }, 7000); return () => { - mounted = false + clearInterval(interval); } - }, [webId]) + }, [webId, notifications]) + return notifications + + + async function updateNotifications(webId, currentNotifications){ + if(webId && await checkNewNotifications(webId, currentNotifications)) { + const updatedNotifications = await fetchNotifications(webId) + setNotifications(updatedNotifications) + } + } + + async function fetchNotifications(webId){ + const notificationsMetadata = await getNotificationMetadata(webId) + if(!notificationsMetadata) return [] + const notificationList = [] + for await (const metadata of notificationsMetadata){ + const notification = await getNotification(metadata.id) + notification.metadata = metadata + notificationList.push(notification) + } + return notificationList + } } export default useNotifications \ No newline at end of file diff --git a/src/util/MarriageController.js b/src/util/MarriageController.js index a42d726..b4e2566 100644 --- a/src/util/MarriageController.js +++ b/src/util/MarriageController.js @@ -73,7 +73,7 @@ export function createAcceptanceNotification(webId, proposalId, authorId){ a as:Invite ; as:actor <${authorId}> ; as:object <${webId}> ; - as:target <${proposalId}> . + as:target <${proposalId}> ; ] ; as:target <${proposalId}> ; as:summary "Acceptance of the offer to participate in the marriage contract" . @@ -89,7 +89,7 @@ export function createRejectionNotification(webId, proposalId, authorId){ a as:Invite ; as:actor <${authorId}> ; as:object <${webId}> ; - as:target <${proposalId}> . + as:target <${proposalId}> ; ] ; as:target <${proposalId}> ; as:summary "Rejection of the offer to participate in the marriage contract" . diff --git a/src/util/notifications.js b/src/util/notifications.js index 7c06970..377fa36 100644 --- a/src/util/notifications.js +++ b/src/util/notifications.js @@ -8,21 +8,28 @@ export default async function notify(notificationBody, subjects) { for (let subject of subjects) { const inbox = await getInbox(subject); if (inbox) postFile(inbox, notificationBody) - else console.error(subject + ' does not have an inbox') } } async function getInbox(subject){ const inbox = await data[subject][ns.ldp('inbox')] + if(!inbox) console.error(subject + ' does not profide an inbox.') return inbox && inbox.value } +export async function checkNewNotifications(webId, currentNotifications) { + if(!currentNotifications) return true + const inbox = await getInbox(webId) + if(!inbox) return false + const store = await getStore(inbox) + let notificationsMetadata = await store.getQuads(inbox, ns.ldp('contains')) + if (notificationsMetadata.length === currentNotifications.length) return false; + return true +} + export async function getNotificationMetadata(webId) { const inbox = await getInbox(webId) - if(!inbox) { - console.error(webId + ' does not profide an inbox.') - return [] - } + if(!inbox) return [] const store = await getStore(inbox) let notificationsMetadata = await store.getQuads(inbox, ns.ldp('contains')) notificationsMetadata = notificationsMetadata.map(quad => { return ( {id: quad.object.value})})