diff --git a/packages/app-root/package.json b/packages/app-root/package.json index 395a5743e1f..a1bae897cdd 100644 --- a/packages/app-root/package.json +++ b/packages/app-root/package.json @@ -25,7 +25,8 @@ "panoptes-client": "~5.5.6", "react": "~18.2.0", "react-dom": "~18.2.0", - "styled-components": "~5.3.10" + "styled-components": "~5.3.10", + "swr": "~2.2.4" }, "engines": { "node": ">=18.13" diff --git a/packages/app-root/src/components/PageHeader.js b/packages/app-root/src/components/PageHeader.js index b6d6a49db15..2ffc97a7d4a 100644 --- a/packages/app-root/src/components/PageHeader.js +++ b/packages/app-root/src/components/PageHeader.js @@ -1,13 +1,21 @@ 'use client' import ZooHeader from '@zooniverse/react-components/ZooHeader' -import { usePanoptesUser } from '../hooks' +import { + usePanoptesUser, + useUnreadMessages, + useUnreadNotifications +} from '../hooks' export default function PageHeader() { const { data: user } = usePanoptesUser() + const { data: unreadMessages }= useUnreadMessages(user) + const { data: unreadNotifications }= useUnreadNotifications(user) return ( ) diff --git a/packages/app-root/src/hooks/index.js b/packages/app-root/src/hooks/index.js index 31b4d47326e..16926d8a139 100644 --- a/packages/app-root/src/hooks/index.js +++ b/packages/app-root/src/hooks/index.js @@ -1 +1,3 @@ export { default as usePanoptesUser } from './usePanoptesUser.js' +export { default as useUnreadMessages } from './useUnreadMessages.js' +export { default as useUnreadNotifications } from './useUnreadNotifications.js' diff --git a/packages/app-root/src/hooks/useUnreadMessages.js b/packages/app-root/src/hooks/useUnreadMessages.js new file mode 100644 index 00000000000..cc348c8bb17 --- /dev/null +++ b/packages/app-root/src/hooks/useUnreadMessages.js @@ -0,0 +1,53 @@ +import { talkAPI } from '@zooniverse/panoptes-js' +import auth from 'panoptes-client/lib/auth' +import useSWR from 'swr' + +const SWROptions = { + revalidateIfStale: true, + revalidateOnMount: true, + revalidateOnFocus: true, + revalidateOnReconnect: true, + refreshInterval: 0 +} + +async function getUnreadConversationsIds(authorization) { + if (!authorization) return [] + + let unreadConversationsIds = [] + + async function getConversations (page = 1) { + const query = { + unread: true, + page: page + } + + const response = await talkAPI.get('/conversations', query, { authorization }) + const { meta, conversations } = response?.body || {} + + if (conversations && conversations.length) { + unreadConversationsIds = unreadConversationsIds.concat( + conversations.map(conversation => conversation.id) + ) + } + + if (meta?.next_page) { + return getConversations(meta.next_page) + } + + return unreadConversationsIds + } + + return getConversations(1) +} + +async function fetchUnreadMessages(user) { + const token = await auth.checkBearerToken() + const authorization = `Bearer ${token}` + + const unreadConversationsIds = await getUnreadConversationsIds(authorization) + return unreadConversationsIds.length +} + +export default function useUnreadMessages(user) { + return useSWR(user, fetchUnreadMessages, SWROptions) +} diff --git a/packages/app-root/src/hooks/useUnreadNotifications.js b/packages/app-root/src/hooks/useUnreadNotifications.js new file mode 100644 index 00000000000..6dd105a0ddd --- /dev/null +++ b/packages/app-root/src/hooks/useUnreadNotifications.js @@ -0,0 +1,34 @@ +import { talkAPI } from '@zooniverse/panoptes-js' +import auth from 'panoptes-client/lib/auth' +import useSWR from 'swr' + +const SWROptions = { + revalidateIfStale: true, + revalidateOnMount: true, + revalidateOnFocus: true, + revalidateOnReconnect: true, + refreshInterval: 0 +} + +async function getUnreadNotificationsCount(authorization) { + if (!authorization) return undefined + + const query = { + delivered: false, + page_size: 1 + } + + const response = await talkAPI.get('/notifications', query, { authorization }) + return response?.body?.meta?.notifications?.count +} + +async function fetchUnreadNotifications(user) { + const token = await auth.checkBearerToken() + const authorization = `Bearer ${token}` + + return await getUnreadNotificationsCount(authorization) +} + +export default function useUnreadMessages(user) { + return useSWR(user, fetchUnreadNotifications, SWROptions) +} diff --git a/yarn.lock b/yarn.lock index 1a5ee4e2662..1236344f4bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2335,34 +2335,6 @@ uuid "^9.0.0" ws "^7.5.9" -"@newrelic/security-agent@0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@newrelic/security-agent/-/security-agent-0.3.0.tgz#95c171b80779c48a2deec8e158e9b3e8eae275fa" - integrity sha512-HdaznRDgUNmTvemuFoFzmv25BI/CMjjFWptMhC5E5PV1HiYJzGnFN0acMKabvqOu+3H0QuDFoKehxqA/4w/xsg== - dependencies: - "@aws-sdk/client-lambda" "^3.363.0" - axios "0.21.4" - check-disk-space "3.3.1" - content-type "^1.0.5" - fast-safe-stringify "^2.1.1" - find-package-json "^1.2.0" - hash.js "^1.1.7" - html-entities "^2.3.6" - is-invalid-path "^1.0.2" - js-yaml "^4.1.0" - jsonschema "^1.4.1" - lodash "^4.17.21" - log4js "^6.9.1" - pretty-bytes "^5.6.0" - request-ip "^3.3.0" - ringbufferjs "^2.0.0" - semver "^7.5.4" - sync-request "^6.1.0" - unescape "^1.0.1" - unescape-js "^1.1.4" - uuid "^9.0.0" - ws "^7.5.9" - "@newrelic/superagent@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/@newrelic/superagent/-/superagent-7.0.0.tgz" @@ -16557,7 +16529,7 @@ swc-loader@^0.2.3: resolved "https://registry.npmjs.org/swc-loader/-/swc-loader-0.2.3.tgz" integrity sha512-D1p6XXURfSPleZZA/Lipb3A8pZ17fP4NObZvFCDjK/OKljroqDpPmsBdTraWhVBqUNpcWBQY1imWdoPScRlQ7A== -swr@~2.2.0: +swr@~2.2.0, swr@~2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/swr/-/swr-2.2.4.tgz#03ec4c56019902fbdc904d78544bd7a9a6fa3f07" integrity sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==