From 56b56927e7faaa52f07b205422194208e0540c55 Mon Sep 17 00:00:00 2001 From: Stef Coenen Date: Wed, 28 Aug 2024 11:26:03 +0200 Subject: [PATCH] Slimmed down the audio wave; (#212) * Slimmed down the audio wave; * Optimistic updates on connections; --- .../common-app/src/hooks/circles/useCircle.ts | 6 +- .../src/hooks/connections/useConnections.ts | 19 ++-- .../hooks/notifications/useNotifications.tsx | 8 +- .../circleNetwork/CircleNetworkProvider.ts | 2 +- packages/owner-app/src/hooks/apps/useApp.ts | 14 +-- .../owner-app/src/hooks/apps/useAppClients.ts | 16 ++-- packages/owner-app/src/hooks/apps/useApps.ts | 2 +- .../owner-app/src/hooks/auth/useYouAuth.ts | 13 --- .../hooks/connections/useConnectionActions.ts | 48 +++++----- .../src/hooks/connections/useDomain.ts | 27 +++--- .../src/hooks/connections/useDomainClients.ts | 4 +- .../src/hooks/connections/useDomains.ts | 2 +- .../hooks/connections/usePendingConnection.ts | 74 ++++++++++----- .../src/hooks/contacts/useContacts.ts | 4 +- .../OdinAudio/OdinAudioWaveForm.tsx | 93 +++++++++++-------- 15 files changed, 184 insertions(+), 148 deletions(-) delete mode 100644 packages/owner-app/src/hooks/auth/useYouAuth.ts diff --git a/packages/common-app/src/hooks/circles/useCircle.ts b/packages/common-app/src/hooks/circles/useCircle.ts index ef5343149..baed04fc8 100644 --- a/packages/common-app/src/hooks/circles/useCircle.ts +++ b/packages/common-app/src/hooks/circles/useCircle.ts @@ -203,7 +203,7 @@ export const useCircle = ({ circleId }: { circleId?: string }) => { queryClient.invalidateQueries({ queryKey: ['circleMembers', circleId] }); await Promise.all( param.domains.map(async (domain) => { - await queryClient.invalidateQueries({ queryKey: ['domainInfo', domain] }); + await queryClient.invalidateQueries({ queryKey: ['domain-info', domain] }); }) ); }, @@ -262,7 +262,7 @@ export const useCircle = ({ circleId }: { circleId?: string }) => { queryClient.invalidateQueries({ queryKey: ['circles'] }); queryClient.invalidateQueries({ queryKey: ['circle', circleId] }); queryClient.invalidateQueries({ queryKey: ['circleMembers', circleId] }); - queryClient.invalidateQueries({ queryKey: ['domainInfo', param.domain] }); + queryClient.invalidateQueries({ queryKey: ['domain-info', param.domain] }); }, onError: (ex) => { console.error(ex); @@ -275,7 +275,7 @@ export const useCircle = ({ circleId }: { circleId?: string }) => { queryClient.invalidateQueries({ queryKey: ['circles'] }); queryClient.invalidateQueries({ queryKey: ['circle', circleId] }); queryClient.invalidateQueries({ queryKey: ['circleMembers', circleId] }); - queryClient.invalidateQueries({ queryKey: ['domainInfo', param.domain] }); + queryClient.invalidateQueries({ queryKey: ['domain-info', param.domain] }); }, onError: (ex) => { console.error(ex); diff --git a/packages/common-app/src/hooks/connections/useConnections.ts b/packages/common-app/src/hooks/connections/useConnections.ts index 9052ee5c0..34ad0700f 100644 --- a/packages/common-app/src/hooks/connections/useConnections.ts +++ b/packages/common-app/src/hooks/connections/useConnections.ts @@ -1,6 +1,11 @@ import { useInfiniteQuery, useQuery } from '@tanstack/react-query'; -import { PagingOptions } from '@homebase-id/js-lib/core'; -import { getConnections, getPendingRequests, getSentRequests } from '@homebase-id/js-lib/network'; +import { NumberCursoredResult, PagingOptions } from '@homebase-id/js-lib/core'; +import { + DotYouProfile, + getConnections, + getPendingRequests, + getSentRequests, +} from '@homebase-id/js-lib/network'; import { useDotYouClient } from '../auth/useDotYouClient'; @@ -28,7 +33,7 @@ export const usePendingConnections = ({ return { fetch: useQuery({ - queryKey: ['pendingConnections', pendingPageSize, pendingPage], + queryKey: ['pending-connections', pendingPageSize, pendingPage], queryFn: () => fetchPendingConnections({ pageSize: pendingPageSize, pageNumber: pendingPage }), @@ -56,7 +61,7 @@ export const useSentConnections = ({ return { fetch: useQuery({ - queryKey: ['sentRequests', sentPageSize, sentPage], + queryKey: ['sent-requests', sentPageSize, sentPage], queryFn: () => fetchSentRequests({ pageSize: sentPageSize, pageNumber: sentPage }), refetchOnWindowFocus: false, enabled: !!sentPage, @@ -88,15 +93,15 @@ export const useActiveConnections = ( }); } catch (ex) { return { - cursor: undefined, + cursor: 0, results: [], - }; + } as NumberCursoredResult; } }; return { fetch: useInfiniteQuery({ - queryKey: ['activeConnections', activePageSize, activePage], + queryKey: ['active-connections', activePageSize, activePage], initialPageParam: undefined as number | undefined, queryFn: ({ pageParam }) => fetchConnections({ pageSize: activePageSize, cursor: pageParam }), getNextPageParam: (lastPage) => diff --git a/packages/common-app/src/hooks/notifications/useNotifications.tsx b/packages/common-app/src/hooks/notifications/useNotifications.tsx index 1c9dc5427..042789c14 100644 --- a/packages/common-app/src/hooks/notifications/useNotifications.tsx +++ b/packages/common-app/src/hooks/notifications/useNotifications.tsx @@ -66,12 +66,12 @@ export const useNotifications = () => { ]); if (wsNotification.notificationType === 'connectionRequestReceived') { - queryClient.invalidateQueries({ queryKey: ['pendingConnections'] }); - queryClient.invalidateQueries({ queryKey: ['pendingConnection'] }); + queryClient.invalidateQueries({ queryKey: ['pending-connections'] }); + queryClient.invalidateQueries({ queryKey: ['pending-connection'] }); } else { // Accepted - queryClient.invalidateQueries({ queryKey: ['sentRequests'] }); - queryClient.invalidateQueries({ queryKey: ['activeConnections'] }); + queryClient.invalidateQueries({ queryKey: ['sent-requests'] }); + queryClient.invalidateQueries({ queryKey: ['active-connections'] }); } } diff --git a/packages/js-lib/src/network/circleNetwork/CircleNetworkProvider.ts b/packages/js-lib/src/network/circleNetwork/CircleNetworkProvider.ts index bd9f3ea19..af7482682 100644 --- a/packages/js-lib/src/network/circleNetwork/CircleNetworkProvider.ts +++ b/packages/js-lib/src/network/circleNetwork/CircleNetworkProvider.ts @@ -35,7 +35,7 @@ export const getConnections = async ( count: number; cursor?: number; } -): Promise> => { +): Promise> => { const client = dotYouClient.createAxiosClient(); const url = root + '/connected?' + stringifyToQueryParams(data); diff --git a/packages/owner-app/src/hooks/apps/useApp.ts b/packages/owner-app/src/hooks/apps/useApp.ts index 07793c0e0..ff1f7ef0d 100644 --- a/packages/owner-app/src/hooks/apps/useApp.ts +++ b/packages/owner-app/src/hooks/apps/useApp.ts @@ -131,7 +131,7 @@ export const useApp = ({ appId }: { appId?: string }) => { mutationFn: registerNewApp, onSuccess: (data, param) => { queryClient.invalidateQueries({ queryKey: ['app', param.appId] }); - queryClient.invalidateQueries({ queryKey: ['registeredApps'] }); + queryClient.invalidateQueries({ queryKey: ['apps'] }); }, onError: (ex) => { console.error(ex); @@ -141,7 +141,7 @@ export const useApp = ({ appId }: { appId?: string }) => { mutationFn: revokeAppInternal, onSuccess: (data, param) => { queryClient.invalidateQueries({ queryKey: ['app', param.appId] }); - queryClient.invalidateQueries({ queryKey: ['registeredApps'] }); + queryClient.invalidateQueries({ queryKey: ['apps'] }); }, onError: (ex) => { console.error(ex); @@ -151,7 +151,7 @@ export const useApp = ({ appId }: { appId?: string }) => { mutationFn: allowAppInternal, onSuccess: (data, param) => { queryClient.invalidateQueries({ queryKey: ['app', param.appId] }); - queryClient.invalidateQueries({ queryKey: ['registeredApps'] }); + queryClient.invalidateQueries({ queryKey: ['apps'] }); }, onError: (ex) => { console.error(ex); @@ -161,7 +161,7 @@ export const useApp = ({ appId }: { appId?: string }) => { mutationFn: removeAppInternal, onSuccess: (data, param) => { queryClient.invalidateQueries({ queryKey: ['app', param.appId] }); - queryClient.invalidateQueries({ queryKey: ['registeredApps'] }); + queryClient.invalidateQueries({ queryKey: ['apps'] }); }, onError: (ex) => { console.error(ex); @@ -171,7 +171,7 @@ export const useApp = ({ appId }: { appId?: string }) => { mutationFn: updateAuthorizedCircles, onSuccess: (data, param) => { queryClient.invalidateQueries({ queryKey: ['app', param.appId] }); - queryClient.invalidateQueries({ queryKey: ['registeredApps'] }); + queryClient.invalidateQueries({ queryKey: ['apps'] }); }, onError: (ex) => { console.error(ex); @@ -181,7 +181,7 @@ export const useApp = ({ appId }: { appId?: string }) => { mutationFn: updatePermissions, onSuccess: (data, param) => { queryClient.invalidateQueries({ queryKey: ['app', param.appId] }); - queryClient.invalidateQueries({ queryKey: ['registeredApps'] }); + queryClient.invalidateQueries({ queryKey: ['apps'] }); }, onError: (ex) => { console.error(ex); @@ -191,7 +191,7 @@ export const useApp = ({ appId }: { appId?: string }) => { mutationFn: extendPermissions, onSuccess: (data, param) => { queryClient.invalidateQueries({ queryKey: ['app', param.appId] }); - queryClient.invalidateQueries({ queryKey: ['registeredApps'] }); + queryClient.invalidateQueries({ queryKey: ['apps'] }); }, onError: (ex) => { console.error(ex); diff --git a/packages/owner-app/src/hooks/apps/useAppClients.ts b/packages/owner-app/src/hooks/apps/useAppClients.ts index 7d00f451c..b6052bb91 100644 --- a/packages/owner-app/src/hooks/apps/useAppClients.ts +++ b/packages/owner-app/src/hooks/apps/useAppClients.ts @@ -67,7 +67,7 @@ export const useAppClients = ({ appId }: { appId?: string }) => { return { fetch: useQuery({ - queryKey: ['appClients', appId], + queryKey: ['app-clients', appId], queryFn: () => fetch({ appId: appId as string }), refetchOnWindowFocus: false, retry: false, @@ -76,7 +76,7 @@ export const useAppClients = ({ appId }: { appId?: string }) => { registerClient: useMutation({ mutationFn: registerClient, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['appClients', param.appId] }); + queryClient.invalidateQueries({ queryKey: ['app-clients', param.appId] }); }, onError: (ex) => { console.error(ex); @@ -85,8 +85,8 @@ export const useAppClients = ({ appId }: { appId?: string }) => { removeClient: useMutation({ mutationFn: removeClient, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['appClients', param.appId] }); - queryClient.invalidateQueries({ queryKey: ['appClients'] }); + queryClient.invalidateQueries({ queryKey: ['app-clients', param.appId] }); + queryClient.invalidateQueries({ queryKey: ['app-clients'] }); }, onError: (ex) => { console.error(ex); @@ -95,8 +95,8 @@ export const useAppClients = ({ appId }: { appId?: string }) => { revokeClient: useMutation({ mutationFn: revokeClient, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['appClients', param.appId] }); - queryClient.invalidateQueries({ queryKey: ['appClients'] }); + queryClient.invalidateQueries({ queryKey: ['app-clients', param.appId] }); + queryClient.invalidateQueries({ queryKey: ['app-clients'] }); }, onError: (ex) => { console.error(ex); @@ -105,8 +105,8 @@ export const useAppClients = ({ appId }: { appId?: string }) => { allowClient: useMutation({ mutationFn: allowClient, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['appClients', param.appId] }); - queryClient.invalidateQueries({ queryKey: ['appClients'] }); + queryClient.invalidateQueries({ queryKey: ['app-clients', param.appId] }); + queryClient.invalidateQueries({ queryKey: ['app-clients'] }); }, onError: (ex) => { console.error(ex); diff --git a/packages/owner-app/src/hooks/apps/useApps.ts b/packages/owner-app/src/hooks/apps/useApps.ts index bf31e4dc8..3d30e1f6c 100644 --- a/packages/owner-app/src/hooks/apps/useApps.ts +++ b/packages/owner-app/src/hooks/apps/useApps.ts @@ -12,7 +12,7 @@ export const useApps = () => { return { fetchRegistered: useQuery({ - queryKey: ['registeredApps'], + queryKey: ['apps'], queryFn: () => fetchRegistered(), refetchOnWindowFocus: false, }), diff --git a/packages/owner-app/src/hooks/auth/useYouAuth.ts b/packages/owner-app/src/hooks/auth/useYouAuth.ts deleted file mode 100644 index 96d944ebf..000000000 --- a/packages/owner-app/src/hooks/auth/useYouAuth.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { useMutation } from '@tanstack/react-query'; -import { createHomeToken } from '../../provider/auth/YouAuthProvider'; - -export const useYouAuth = () => { - return { - homeToken: useMutation({ - mutationFn: createHomeToken, - onError: (err) => { - console.error(err); - }, - }), - }; -}; diff --git a/packages/owner-app/src/hooks/connections/useConnectionActions.ts b/packages/owner-app/src/hooks/connections/useConnectionActions.ts index 87d5fc78d..2923f82b4 100644 --- a/packages/owner-app/src/hooks/connections/useConnectionActions.ts +++ b/packages/owner-app/src/hooks/connections/useConnectionActions.ts @@ -10,7 +10,8 @@ import { import { saveContact } from '../../provider/contact/ContactProvider'; import { fetchConnectionInfo } from '../../provider/contact/ContactSourceProvider'; import { useAuth } from '../auth/useAuth'; -import { SecurityGroupType } from '@homebase-id/js-lib/core'; +import { PagedResult, SecurityGroupType } from '@homebase-id/js-lib/core'; +import { getNewId } from '@homebase-id/js-lib/helpers'; export const useConnectionActions = () => { const queryClient = useQueryClient(); @@ -57,7 +58,7 @@ export const useConnectionActions = () => { disconnect: useMutation({ mutationFn: disconnect, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['activeConnections'] }); + queryClient.invalidateQueries({ queryKey: ['active-connections'] }); queryClient.invalidateQueries({ queryKey: ['connection-info', param.connectionOdinId] }); }, onError: (ex) => { @@ -67,38 +68,43 @@ export const useConnectionActions = () => { sendConnectionRequest: useMutation({ mutationFn: sendConnectionRequest, - onMutate: async (newRequest) => { - await queryClient.cancelQueries({ queryKey: ['sentRequests'] }); + onMutate: async ({ targetOdinId, message }) => { + await queryClient.cancelQueries({ queryKey: ['sent-requests'] }); - const previousRequests: ConnectionRequest[] | undefined = queryClient.getQueryData([ - 'sentRequests', + const previousRequests = queryClient.getQueryData>([ + 'sent-requests', ]); - const newRequests = [ - { - status: 'sent', - recipient: newRequest.targetOdinId, - }, - ...(previousRequests ?? []), - ]; - queryClient.setQueryData(['sentRequests'], newRequests); + const newRequest: ConnectionRequest = { + status: 'sent', + recipient: targetOdinId, + id: getNewId(), + message: message, + senderOdinId: dotYouClient.getIdentity(), + receivedTimestampMilliseconds: Date.now(), + }; + queryClient.setQueryData>(['sent-requests'], { + totalPages: 0, + ...previousRequests, + results: [newRequest, ...(previousRequests?.results || [])], + }); return { previousRequests, newRequest }; }, onError: (err, newData, context) => { console.error(err); - queryClient.setQueryData(['sentRequests'], context?.previousRequests); + queryClient.setQueryData(['sent-requests'], context?.previousRequests); }, onSettled: (data) => { - queryClient.invalidateQueries({ queryKey: ['sentRequests'] }); + queryClient.invalidateQueries({ queryKey: ['sent-requests'] }); queryClient.invalidateQueries({ queryKey: ['connection-info', data?.targetOdinId] }); }, }), revokeConnectionRequest: useMutation({ mutationFn: revokeConnectionRequest, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['sentRequests'] }); + queryClient.invalidateQueries({ queryKey: ['sent-requests'] }); queryClient.invalidateQueries({ queryKey: ['connection-info', param.targetOdinId] }); }, onError: (ex) => { @@ -108,16 +114,16 @@ export const useConnectionActions = () => { block: useMutation({ mutationFn: block, onSettled: (_data, _err, odinId) => { - queryClient.invalidateQueries({ queryKey: ['pendingConnections'] }); - queryClient.invalidateQueries({ queryKey: ['activeConnections'] }); + queryClient.invalidateQueries({ queryKey: ['pending-connections'] }); + queryClient.invalidateQueries({ queryKey: ['active-connections'] }); queryClient.invalidateQueries({ queryKey: ['connection-info', odinId] }); }, }), unblock: useMutation({ mutationFn: unblock, onSettled: (_data, _err, odinId) => { - queryClient.invalidateQueries({ queryKey: ['pendingConnections'] }); - queryClient.invalidateQueries({ queryKey: ['activeConnections'] }); + queryClient.invalidateQueries({ queryKey: ['pending-connections'] }); + queryClient.invalidateQueries({ queryKey: ['active-connections'] }); queryClient.invalidateQueries({ queryKey: ['connection-info', odinId] }); }, }), diff --git a/packages/owner-app/src/hooks/connections/useDomain.ts b/packages/owner-app/src/hooks/connections/useDomain.ts index 757b9c42a..e1c670698 100644 --- a/packages/owner-app/src/hooks/connections/useDomain.ts +++ b/packages/owner-app/src/hooks/connections/useDomain.ts @@ -25,28 +25,25 @@ export const useDomain = ({ domain }: { domain?: string }) => { return await getDomainClients(dotYouClient, domain); }; - const revokeDomain = async ({ domain }: { domain: string }) => { - return await revokeDomainAccess(dotYouClient, domain); - }; + const revokeDomain = async ({ domain }: { domain: string }) => + await revokeDomainAccess(dotYouClient, domain); - const restoreDomain = async ({ domain }: { domain: string }) => { - return await restoreDomainAccess(dotYouClient, domain); - }; + const restoreDomain = async ({ domain }: { domain: string }) => + await restoreDomainAccess(dotYouClient, domain); - const removeDomain = async ({ domain }: { domain: string }) => { - return await disconnectFromDomain(dotYouClient, domain); - }; + const removeDomain = async ({ domain }: { domain: string }) => + await disconnectFromDomain(dotYouClient, domain); return { fetch: useQuery({ - queryKey: ['domainInfo', domain], + queryKey: ['domain-info', domain], queryFn: () => fetchSingle({ domain: domain as string }), refetchOnWindowFocus: false, enabled: !!domain, }), fetchClients: useQuery({ - queryKey: ['domainClients', domain], + queryKey: ['domain-clients', domain], queryFn: () => fetchClients({ domain: domain as string }), refetchOnWindowFocus: false, @@ -56,7 +53,7 @@ export const useDomain = ({ domain }: { domain?: string }) => { revokeDomain: useMutation({ mutationFn: revokeDomain, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['domainInfo', param.domain] }); + queryClient.invalidateQueries({ queryKey: ['domain-info', param.domain] }); }, onError: (ex) => { console.error(ex); @@ -66,7 +63,7 @@ export const useDomain = ({ domain }: { domain?: string }) => { restoreDomain: useMutation({ mutationFn: restoreDomain, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['domainInfo', param.domain] }); + queryClient.invalidateQueries({ queryKey: ['domain-info', param.domain] }); }, onError: (ex) => { console.error(ex); @@ -76,8 +73,8 @@ export const useDomain = ({ domain }: { domain?: string }) => { disconnect: useMutation({ mutationFn: removeDomain, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['activeDomains'] }); - queryClient.invalidateQueries({ queryKey: ['domainInfo', param.domain] }); + queryClient.invalidateQueries({ queryKey: ['active-domains'] }); + queryClient.invalidateQueries({ queryKey: ['domain-info', param.domain] }); }, onError: (ex) => { console.error(ex); diff --git a/packages/owner-app/src/hooks/connections/useDomainClients.ts b/packages/owner-app/src/hooks/connections/useDomainClients.ts index bfb993fc9..57c5f3ce0 100644 --- a/packages/owner-app/src/hooks/connections/useDomainClients.ts +++ b/packages/owner-app/src/hooks/connections/useDomainClients.ts @@ -27,7 +27,7 @@ export const useDomainClients = ({ domain }: { domain?: string }) => { return { fetch: useQuery({ - queryKey: ['domainClients', domain], + queryKey: ['domain-clients', domain], queryFn: () => fetchClients({ domain: domain as string }), refetchOnWindowFocus: false, enabled: !!domain, @@ -36,7 +36,7 @@ export const useDomainClients = ({ domain }: { domain?: string }) => { removeClient: useMutation({ mutationFn: removeClient, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['domainClients', param.domain] }); + queryClient.invalidateQueries({ queryKey: ['domain-clients', param.domain] }); }, onError: (ex) => { console.error(ex); diff --git a/packages/owner-app/src/hooks/connections/useDomains.ts b/packages/owner-app/src/hooks/connections/useDomains.ts index a90577279..8ed4dafc9 100644 --- a/packages/owner-app/src/hooks/connections/useDomains.ts +++ b/packages/owner-app/src/hooks/connections/useDomains.ts @@ -34,7 +34,7 @@ export const useDomains = ( return { fetch: useInfiniteQuery({ - queryKey: ['activeDomains', activePageSize, activePage], + queryKey: ['active-domains', activePageSize, activePage], queryFn: ({ pageParam }) => fetchDomains({ pageSize: activePageSize, cursor: pageParam }), initialPageParam: undefined as number | undefined, getNextPageParam: (lastPage) => diff --git a/packages/owner-app/src/hooks/connections/usePendingConnection.ts b/packages/owner-app/src/hooks/connections/usePendingConnection.ts index 15f0c7147..1e2ba2c9f 100644 --- a/packages/owner-app/src/hooks/connections/usePendingConnection.ts +++ b/packages/owner-app/src/hooks/connections/usePendingConnection.ts @@ -1,14 +1,16 @@ -import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { InfiniteData, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useAuth } from '../auth/useAuth'; import { ConnectionRequest, + DotYouProfile, acceptConnectionRequest, deletePendingRequest, getPendingRequest, } from '@homebase-id/js-lib/network'; import { saveContact } from '../../provider/contact/ContactProvider'; import { fetchConnectionInfo } from '../../provider/contact/ContactSourceProvider'; -import { SecurityGroupType } from '@homebase-id/js-lib/core'; +import { NumberCursoredResult, SecurityGroupType } from '@homebase-id/js-lib/core'; +import { getNewId } from '@homebase-id/js-lib/helpers'; export const usePendingConnection = ({ odinId }: { odinId?: string }) => { const queryClient = useQueryClient(); @@ -46,7 +48,7 @@ export const usePendingConnection = ({ odinId }: { odinId?: string }) => { return { fetch: useQuery({ - queryKey: ['pendingConnection', odinId], + queryKey: ['pending-connection', odinId], queryFn: () => getPendingConnectionInfo({ odinId: odinId as string }), refetchOnWindowFocus: false, @@ -55,40 +57,68 @@ export const usePendingConnection = ({ odinId }: { odinId?: string }) => { acceptRequest: useMutation({ mutationFn: acceptRequest, onMutate: async (newRequest) => { - await queryClient.cancelQueries({ queryKey: ['activeConnections'] }); + // Update active connections + await queryClient.cancelQueries({ queryKey: ['active-connections'] }); - const previousConnections: ConnectionRequest[] | undefined = queryClient.getQueryData([ - 'activeConnections', - ]); - const newConnections = [ - { - status: 'pending', // Set to pending to not update the connetion details page yet, as we don't have the data for that - odinId: newRequest.senderOdinId, - }, - ...(previousConnections ?? []), - ]; + const previousConnections = queryClient.getQueryData< + InfiniteData> + >(['active-connections']); + + const newConnections = { + pageParams: [], + ...previousConnections, + pages: + previousConnections?.pages.map((page, index) => + index === 0 + ? { + ...page, + data: [ + ...page.results, + { + odinId: newRequest.senderOdinId, + }, + ], + } + : page + ) || [], + }; + + queryClient.setQueryData>>( + ['active-connections'], + newConnections + ); - queryClient.setQueryData(['activeConnections'], newConnections); + // Update pending connections + await queryClient.cancelQueries({ queryKey: ['pending-connections'] }); + + const previousPending: ConnectionRequest[] | undefined = queryClient.getQueryData([ + 'pending-connections', + ]); + queryClient.setQueryData( + ['pending-connections'], + previousPending?.filter((r) => r.recipient !== newRequest.senderOdinId) + ); - return { previousConnections, newRequest }; + return { previousConnections, previousPending, newRequest }; }, onError: (err, newData, context) => { console.error(err); - queryClient.setQueryData(['activeConnections'], context?.previousConnections); + queryClient.setQueryData(['active-connections'], context?.previousConnections); + queryClient.setQueryData(['pending-connections'], context?.previousPending); }, onSettled: (data) => { - queryClient.invalidateQueries({ queryKey: ['pendingConnections'] }); - queryClient.invalidateQueries({ queryKey: ['pendingConnection', data?.senderOdinId] }); - queryClient.invalidateQueries({ queryKey: ['activeConnections'] }); + queryClient.invalidateQueries({ queryKey: ['pending-connections'] }); + queryClient.invalidateQueries({ queryKey: ['pending-connection', data?.senderOdinId] }); + queryClient.invalidateQueries({ queryKey: ['active-connections'] }); queryClient.invalidateQueries({ queryKey: ['connection-info', data?.senderOdinId] }); }, }), ignoreRequest: useMutation({ mutationFn: ignoreRequest, onSuccess: (data, param) => { - queryClient.invalidateQueries({ queryKey: ['pendingConnections'] }); - queryClient.invalidateQueries({ queryKey: ['pendingConnection', param.senderOdinId] }); + queryClient.invalidateQueries({ queryKey: ['pending-connections'] }); + queryClient.invalidateQueries({ queryKey: ['pending-connection', param.senderOdinId] }); queryClient.invalidateQueries({ queryKey: ['connection-info', param.senderOdinId] }); }, onError: (ex) => { diff --git a/packages/owner-app/src/hooks/contacts/useContacts.ts b/packages/owner-app/src/hooks/contacts/useContacts.ts index 44306cacd..2e55fc03e 100644 --- a/packages/owner-app/src/hooks/contacts/useContacts.ts +++ b/packages/owner-app/src/hooks/contacts/useContacts.ts @@ -3,7 +3,7 @@ import { CursoredResult, NewHomebaseFile } from '@homebase-id/js-lib/core'; import { useAuth } from '../auth/useAuth'; import { parseContact } from './useContact'; -import { RawContact, getContacts } from '@homebase-id/js-lib/network'; +import { ContactVm, RawContact, getContacts } from '@homebase-id/js-lib/network'; const pageSize = 10; @@ -12,7 +12,7 @@ export const useContacts = () => { const fetch = async ( cursorState?: string - ): Promise[]>> => { + ): Promise[]>> => { const data = await await getContacts(dotYouClient, cursorState, pageSize); return { ...data, results: data.results.map((contact) => parseContact(contact)) }; }; diff --git a/packages/ui-lib/src/components/OdinAudio/OdinAudioWaveForm.tsx b/packages/ui-lib/src/components/OdinAudio/OdinAudioWaveForm.tsx index 73ea531a4..b1ae8db0b 100644 --- a/packages/ui-lib/src/components/OdinAudio/OdinAudioWaveForm.tsx +++ b/packages/ui-lib/src/components/OdinAudio/OdinAudioWaveForm.tsx @@ -44,51 +44,62 @@ export const OdinAudioWaveForm = (props: OdinAudioWaveformProps) => { const [isNoData, setIsNoData] = useState(false); const drawToCanvas = async (audioBlob: Blob) => { - if (!canvasRef.current || !sizeDivRef.current) return; - const ctx = canvasRef.current.getContext('2d'); - if (!ctx) return; - - const ac = new AudioContext(); - const { clientHeight: height, clientWidth: width } = sizeDivRef.current; - const centerHeight = Math.ceil(height / 2); - - const buffer = await audioBlob.arrayBuffer(); - const audioBuffer = await ac.decodeAudioData(buffer); - const float32Array = audioBuffer.getChannelData(0); - - const chunkedArray = []; - const chunkSize = Math.ceil(float32Array.length / width); // Make it fit in the avaialble width - - let i = 0; - const length = float32Array.length; - while (i < length) { - chunkedArray.push( - float32Array - .slice(i, (i += chunkSize)) - .reduce((total, value) => total + Math.abs(value), 0) / chunkSize - ); + if (!canvasRef.current || !sizeDivRef.current) { + setIsNoData(true); + return; } - - if (!canvasRef.current) return; - canvasRef.current.height = height; - canvasRef.current.width = width; - - const maxValue = Math.max(...chunkedArray) * height; - const maxHeight = height * 0.7; - const scaleFactor = (maxHeight / maxValue) * maxHeight; // Make it fit in the available height - - if (maxValue === 0) { + const ctx = canvasRef.current.getContext('2d'); + if (!ctx) { setIsNoData(true); return; } - for (const index in chunkedArray) { - ctx.strokeStyle = isDarkMode ? '#fafafa' : '#161616'; - ctx.lineCap = 'round'; - ctx.beginPath(); - ctx.moveTo(Number(index), centerHeight - chunkedArray[index] * scaleFactor); - ctx.lineTo(Number(index), centerHeight + chunkedArray[index] * scaleFactor); - ctx.stroke(); + try { + const ac = new AudioContext(); + const { clientHeight: height, clientWidth: width } = sizeDivRef.current; + const centerHeight = Math.ceil(height / 2); + + const buffer = await audioBlob.arrayBuffer(); + const audioBuffer = await ac.decodeAudioData(buffer); + const float32Array = audioBuffer.getChannelData(0); + + const chunkedArray = []; + const chunkSize = Math.ceil(float32Array.length / width); // Make it fit in the avaialble width + + let i = 0; + const length = float32Array.length; + while (i < length) { + chunkedArray.push( + float32Array + .slice(i, (i += chunkSize)) + .reduce((total, value) => total + Math.abs(value), 0) / chunkSize + ); + } + + if (!canvasRef.current) return; + canvasRef.current.height = height; + canvasRef.current.width = width; + + const maxValue = Math.max(...chunkedArray) * height; + const maxHeight = height * 0.7; + const scaleFactor = (maxHeight / maxValue) * maxHeight; // Make it fit in the available height + + if (maxValue === 0) { + setIsNoData(true); + return; + } + + for (const index in chunkedArray) { + ctx.strokeStyle = isDarkMode ? '#fafafa' : '#161616'; + ctx.lineCap = 'round'; + ctx.beginPath(); + ctx.moveTo(Number(index), centerHeight - chunkedArray[index] * scaleFactor); + ctx.lineTo(Number(index), centerHeight + chunkedArray[index] * scaleFactor); + ctx.stroke(); + } + setIsNoData(false); + } catch (e) { + setIsNoData(true); } }; @@ -106,7 +117,7 @@ export const OdinAudioWaveForm = (props: OdinAudioWaveformProps) => {
{isNoData ? (

{'No audio data'}