From 2f5a6ae241c2493aa0c796c42bfc1079b13ff6f9 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Thu, 14 Jul 2022 11:22:21 -0700 Subject: [PATCH] support resyncing offsync contacts --- .../src/User/SideBar/Contacts/Cards/Cards.jsx | 16 ++++++- .../SideBar/Contacts/Cards/Cards.styled.js | 5 ++ .../SideBar/Contacts/Cards/useCards.hook.js | 3 ++ net/web/src/context/useCardContext.hook.js | 48 +++++++++++++++++-- 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/net/web/src/User/SideBar/Contacts/Cards/Cards.jsx b/net/web/src/User/SideBar/Contacts/Cards/Cards.jsx index 3176ce16..2fb6502e 100644 --- a/net/web/src/User/SideBar/Contacts/Cards/Cards.jsx +++ b/net/web/src/User/SideBar/Contacts/Cards/Cards.jsx @@ -1,9 +1,10 @@ import React, { useEffect } from 'react' -import { CardsWrapper, CardItem } from './Cards.styled'; -import { Drawer, List } from 'antd'; +import { CardsWrapper, CardItem, Offsync } from './Cards.styled'; +import { Drawer, List, Tooltip } from 'antd'; import { Registry } from './Registry/Registry'; import { useCards } from './useCards.hook'; import { Logo } from '../../../../Logo/Logo'; +import { ExclamationCircleOutlined } from '@ant-design/icons'; export function Cards({ showRegistry }) { @@ -38,6 +39,10 @@ export function Cards({ showRegistry }) { return null; } + const Resync = (id) => { + actions.resync(id); + } + return ( + {item.error && ( + + {e.stopPropagation(); Resync(item.id)}} > + + + + )}
{ cardProfile(item).name } { cardHandle(item) } diff --git a/net/web/src/User/SideBar/Contacts/Cards/Cards.styled.js b/net/web/src/User/SideBar/Contacts/Cards/Cards.styled.js index 242bfca6..c4419b9e 100644 --- a/net/web/src/User/SideBar/Contacts/Cards/Cards.styled.js +++ b/net/web/src/User/SideBar/Contacts/Cards/Cards.styled.js @@ -51,3 +51,8 @@ export const CardItem = styled(List.Item)` } `; +export const Offsync = styled.div` + padding-left: 4px; + color: #ff8888; +` + diff --git a/net/web/src/User/SideBar/Contacts/Cards/useCards.hook.js b/net/web/src/User/SideBar/Contacts/Cards/useCards.hook.js index 9fa00b30..4df9111f 100644 --- a/net/web/src/User/SideBar/Contacts/Cards/useCards.hook.js +++ b/net/web/src/User/SideBar/Contacts/Cards/useCards.hook.js @@ -18,6 +18,9 @@ export function useCards() { getImageUrl: card.actions.getImageUrl, select: (contact) => { navigate(`/user/contact/${contact.data.cardProfile.guid}`); + }, + resync: (id) => { + card.actions.resync(id); } }; diff --git a/net/web/src/context/useCardContext.hook.js b/net/web/src/context/useCardContext.hook.js index b4f69df9..38e76c17 100644 --- a/net/web/src/context/useCardContext.hook.js +++ b/net/web/src/context/useCardContext.hook.js @@ -32,18 +32,37 @@ export function useCardContext() { const revision = useRef(null); const next = useRef(null); const cards = useRef(new Map()); + const resync = useRef([]); const updateState = (value) => { setState((s) => ({ ...s, ...value })) } + const updateCard = async (cardId) => { + let card = cards.current.get(cardId); + const { cardDetail, cardProfile } = card.data; + + if (cardDetail.status === 'connected' && card.error) { + let message = await getContactProfile(cardProfile.node, cardProfile.guid, cardDetail.token); + await setCardProfile(access.current, card.id, message); + + card.channels = new Map(); + await updateContactChannels(card.data.cardProfile.node, card.id, card.data.cardProfile.guid, card.data.cardDetail.token, null, null, card.channels); + + card.data.articles = new Map(); + await updateContactArticles(card.data.cardProfile.node, card.id, card.data.cardProfile.guid, card.data.cardDetail.token, null, null, card.data.articles); + + cards.current.set(card.id, { ...card, error: false }); + } + } + const updateCards = async () => { let delta = await getCards(access.current, revision.current); for (let card of delta) { if (card.data) { let cur = cards.current.get(card.id); if (cur == null) { - cur = { id: card.id, data: { articles: new Map() }, channels: new Map() } + cur = { id: card.id, data: { articles: new Map() }, error: false, channels: new Map() } } if (cur.data.detailRevision != card.data.detailRevision) { if (card.data.cardDetail != null) { @@ -64,7 +83,7 @@ export function useCardContext() { cur.data.profileRevision = card.data.profileRevision; } const { cardDetail, cardProfile } = cur.data; - if (cardDetail.status === 'connected') { + if (cardDetail.status === 'connected' && !cur.error) { try { if (cur.data.profileRevision != card.data.notifiedProfile) { let message = await getContactProfile(cardProfile.node, cardProfile.guid, cardDetail.token); @@ -103,7 +122,7 @@ export function useCardContext() { cur.channels = new Map(); cur.articles = new Map(); cur.revision = 0; - cards.current.set(card.id, { ...cur }); + cards.current.set(card.id, { ...cur, error: true }); continue; } } @@ -163,6 +182,9 @@ export function useCardContext() { const setCards = async (rev) => { if (next.current == null) { + if (rev == null) { + rev = revision.curren; + } next.current = rev; if (revision.current != rev) { try { @@ -174,6 +196,18 @@ export function useCardContext() { updateState({ init: true, cards: cards.current }); revision.current = rev; } + + while (resync.current.length) { + try { + await updateCard(resync.current.shift()); + updateState({ cards: cards.current }); + } + catch (err) { + console.log(err); + window.alert("failed to connect to contact"); + } + } + let r = next.current; next.current = null; if (revision.current != r) { @@ -181,7 +215,9 @@ export function useCardContext() { } } else { - next.current = rev; + if (rev != null) { + next.current = rev; + } } } @@ -307,6 +343,10 @@ export function useCardContext() { let node = card.data.cardProfile.node; let token = card.data.cardProfile.guid + "." + card.data.cardDetail.token; return getContactChannelTopicAssetUrl(node, token, channelId, topicId, assetId); + }, + resync: (cardId) => { + resync.current.push(cardId); + setCards(null); } }