diff --git a/README.md b/README.md index 5139de9d..347ae4da 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ make install # installs built binary in $GOPATH/bin dgraph ``` +**Alternative** for step **1)**: find Unigraph's Dgraph binary for your platform on [GitHub Releases](https://github.com/unigraph-dev/dgraph/releases) and rename it to `dgraph`. On Linux or macOS, you'll need to make it executable: `chmod +x ./Downloads/dgraph`. Then, continue to step **2)**. **2)** In the `unigraph` project root, fetch and build project dependencies: diff --git a/packages/default-packages/unigraph.email/executables/addEmailMessage.js b/packages/default-packages/unigraph.email/executables/addEmailMessage.js index 35a1b5b8..49e19377 100644 --- a/packages/default-packages/unigraph.email/executables/addEmailMessage.js +++ b/packages/default-packages/unigraph.email/executables/addEmailMessage.js @@ -11,12 +11,19 @@ const getQuery = (msgid) => `(func: uid(parIds)) @cascade { } }`; -const dest = parsed.map((el) => { +const dest = parsed.map((el, index) => { return { name: { type: { 'unigraph.id': '$/schema/note' }, _value: el.subject || '', }, + ...(msgs[index].externalUrl + ? { + $context: { + _externalUrl: msgs[index].externalUrl, + }, + } + : {}), message_id: el.messageId, message: { date_received: el.date?.toISOString?.() || new Date(0).toISOString(), @@ -97,28 +104,29 @@ for (let i = 0; i < toAddChunks.length; i += 1) { } } -const inboxEntries = await unigraph.getObject('$/entity/inbox').then((x) => x._value.children._value ?? []); -const inboxEntryUids = inboxEntries.map((x) => x._value._value.uid); +// const inboxEntries = await unigraph.getObject('$/entity/inbox').then((x) => x._value.children._value ?? []); +// const inboxEntryUids = inboxEntries.map((x) => x._value._value.uid); -const mirrorEmailInbox = unigraph.getState('settings/email/mirrorEmailInbox').value; +// const mirrorEmailInbox = unigraph.getState('settings/email/mirrorEmailInbox').value; uids.forEach((el, index) => { - // if (!readMask[index] && el) inboxEls.push(el); - const elShouldBeInbox = (mirrorEmailInbox ? inboxMask[index] : !readMask[index]) && el; - const elInInbox = inboxEntryUids.includes(el); - if (elShouldBeInbox && !elInInbox) inboxEls.push(el); + if (inboxMask[index] && el) inboxEls.push(el); + // const elShouldBeInbox = (mirrorEmailInbox ? inboxMask[index] : !readMask[index]) && el; + // const elInInbox = inboxEntryUids.includes(el); + // if (elShouldBeInbox && !elInInbox) inboxEls.push(el); }); await unigraph.runExecutable('$/executable/add-item-to-list', { where: '$/entity/inbox', item: inboxEls.reverse(), }); -setTimeout( - () => - unigraph.addNotification({ - name: 'Inboxes synced', - from: 'unigraph.email', - content: `Added ${count} emails (${inboxEls.length} unread).`, - actions: [], - }), - 1000, -); +if (count > 0) + setTimeout( + () => + unigraph.addNotification({ + name: 'Inboxes synced', + from: 'unigraph.email', + content: `Added ${count} emails (${inboxEls.length} in inbox).`, + actions: [], + }), + 1000, + ); diff --git a/packages/default-packages/unigraph.email/executables/updateGmailInbox.js b/packages/default-packages/unigraph.email/executables/updateGmailInbox.js index 824672c4..414bc7c4 100644 --- a/packages/default-packages/unigraph.email/executables/updateGmailInbox.js +++ b/packages/default-packages/unigraph.email/executables/updateGmailInbox.js @@ -99,8 +99,21 @@ const updateAccountInbox = async (account) => { messages.map((id) => gmail.users.messages.get({ userId: 'me', id, format: 'raw' })), ); const inbox = await unigraph.getObject('$/entity/inbox'); - const inboxEntries = inbox._value.children['_value['] ?? []; + const inboxEntries = (inbox._value.children['_value['] ?? []).filter( + (x) => x._value._value.type?.['unigraph.id'] === '$/schema/email_message', + ); const inboxEntryUids = inboxEntries.map((x) => x._value._value.uid); + const inboxEntryMsgIds = inboxEntries + .map((x) => [x._value._value?._value?.message_id?.['_value.%'], x._value._value.uid]) + .filter(Boolean); + const gmailIdsForCurrentInbox = await Promise.all( + inboxEntryMsgIds.map((el) => + gmail.users.messages.list({ userId: 'me', q: `rfc822msgid:${el[0]}`, labelIds: ['INBOX'] }), + ), + ); + const uidsToRemoveInbox = gmailIdsForCurrentInbox + .map((el, idx) => (el.data?.messages?.length > 0 ? undefined : inboxEntryMsgIds[idx][1])) + .filter(Boolean); const getOldUid = _.curry((condition, el, index) => { const isCondition = condition(el); @@ -111,14 +124,12 @@ const updateAccountInbox = async (account) => { (el) => el.data.labelIds?.includes('TRASH') || el.data.labelIds?.includes('SPAM'), ); const isOldAndInOriginInbox = getOldUid((el) => el.data.labelIds?.includes('INBOX')); - const isOldAndNotInOriginInbox = getOldUid((el) => !el.data.labelIds?.includes('INBOX')); const uidsToDelete = msgResps.map(isOldAndInOriginTrash).filter((el) => el !== undefined); const uidsToInbox = msgResps .map(isOldAndInOriginInbox) .filter((el) => el !== undefined) .filter((x) => !inboxEntryUids.includes(x)); - const uidsToRemoveInbox = msgResps.map(isOldAndNotInOriginInbox).filter((el) => el !== undefined); // TODO: remove or hide deleted msgs @@ -132,6 +143,7 @@ const updateAccountInbox = async (account) => { dont_check_unique: true, messages: newMsgResps.map((el) => ({ message: Buffer.from(el.data.raw, 'base64').toString(), + externalUrl: `https://mail.google.com/mail/u/${account._value.username['_value.%']}/#all/${el.data.id}`, read: !el.data.labelIds?.includes('UNREAD'), inbox: el.data.labelIds?.includes('INBOX'), })), diff --git a/packages/default-packages/unigraph.semantic/executables/renameEntity.js b/packages/default-packages/unigraph.semantic/executables/renameEntity.js index 059cc9a5..3a2b26c5 100644 --- a/packages/default-packages/unigraph.semantic/executables/renameEntity.js +++ b/packages/default-packages/unigraph.semantic/executables/renameEntity.js @@ -72,10 +72,9 @@ const updateTriplets = [`<${oldNameRef.uid}> <_value.%> "${newName}" .`]; (oldRefName['_value.%'].includes(oldName) || force) ) updateTriplets.push( - `<${oldRefName.uid}> <_value.%> "${oldRefName['_value.%'].replaceAll( - `[[${oldName}]]`, - `[[${newName}]]`, - )}" .`, + `<${oldRefName.uid}> <_value.%> "${oldRefName['_value.%'] + .replaceAll(`[[${oldName}]]`, `[[${newName}]]`) + .replace(/"/g, '\\"')}" .`, ); }); diff --git a/packages/unigraph-dev-explorer/public/favicon.ico b/packages/unigraph-dev-explorer/public/favicon.ico index bcd5dfd6..5dd607d2 100644 Binary files a/packages/unigraph-dev-explorer/public/favicon.ico and b/packages/unigraph-dev-explorer/public/favicon.ico differ diff --git a/packages/unigraph-dev-explorer/public/logo192.png b/packages/unigraph-dev-explorer/public/logo192.png index fc44b0a3..1eff5998 100644 Binary files a/packages/unigraph-dev-explorer/public/logo192.png and b/packages/unigraph-dev-explorer/public/logo192.png differ diff --git a/packages/unigraph-dev-explorer/public/logo512.png b/packages/unigraph-dev-explorer/public/logo512.png index a4e47a65..0a76e4c5 100644 Binary files a/packages/unigraph-dev-explorer/public/logo512.png and b/packages/unigraph-dev-explorer/public/logo512.png differ diff --git a/packages/unigraph-dev-explorer/src/examples/email/Email.tsx b/packages/unigraph-dev-explorer/src/examples/email/Email.tsx index 1b943510..85346432 100644 --- a/packages/unigraph-dev-explorer/src/examples/email/Email.tsx +++ b/packages/unigraph-dev-explorer/src/examples/email/Email.tsx @@ -90,7 +90,13 @@ const EmailMessage: DynamicViewRenderer = ({ data, callbacks }) => { secondary={[ Sugar.Date.relative(new Date(unpadded?.message?.date_received)),
- + { + ev.stopPropagation(); + window.open(data._externalUrl, '_blank'); + }} + /> {`${unpadded.content?.abstract}...`}
, ]} diff --git a/packages/unigraph-dev-explorer/src/examples/reddit/RedditPost.tsx b/packages/unigraph-dev-explorer/src/examples/reddit/RedditPost.tsx index 0b9c0a65..90c52108 100644 --- a/packages/unigraph-dev-explorer/src/examples/reddit/RedditPost.tsx +++ b/packages/unigraph-dev-explorer/src/examples/reddit/RedditPost.tsx @@ -60,11 +60,6 @@ export const RedditPost: DynamicViewRenderer = ({ data, callbacks }) => { return (
-
- -

Vote

- -