From bdb77871cde1d45dc0fb1f5f4ccb06d48e1e3344 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Tue, 17 Jan 2023 23:42:22 -0800 Subject: [PATCH] refactor of channel view in webapp --- net/web/src/context/sealUtil.js | 29 +- net/web/src/context/useCardContext.hook.js | 26 +- net/web/src/context/useChannelContext.hook.js | 18 -- .../context/useConversationContext.hook.js | 12 +- net/web/src/session/channels/Channels.jsx | 4 +- .../channels/channelItem/ChannelItem.jsx | 22 +- .../channelItem/useChannelItem.hook.js | 253 ------------------ .../src/session/channels/useChannels.hook.js | 187 ++++++++++++- .../conversation/addTopic/AddTopic.jsx | 4 +- .../conversation/useConversation.hook.js | 2 +- net/web/test/Channel.test.js | 12 - net/web/test/Conversation.test.js | 5 +- 12 files changed, 216 insertions(+), 358 deletions(-) delete mode 100644 net/web/src/session/channels/channelItem/useChannelItem.hook.js diff --git a/net/web/src/context/sealUtil.js b/net/web/src/context/sealUtil.js index 4431b516..54e79a53 100644 --- a/net/web/src/context/sealUtil.js +++ b/net/web/src/context/sealUtil.js @@ -1,22 +1,26 @@ import CryptoJS from 'crypto-js'; import { JSEncrypt } from 'jsencrypt' -export function isUnsealed(subject, sealKey) { +export function getChannelSeals(subject) { const { seals } = JSON.parse(subject); + return seals; +} + +export function isUnsealed(seals, sealKey) { for (let i = 0; i < seals?.length; i++) { - if (seals[i].publicKey === sealKey.public) { - return sealKey.private != null; + if (seals[i].publicKey === sealKey?.public) { + return sealKey?.private != null; } } return false; } -export function getContentKey(subject, sealKey) { - for (let i = 0; i < seal?.length; i++) { - if (seal[i].publicKey === sealKey.public) { +export function getContentKey(seals, sealKey) { + for (let i = 0; i < seals?.length; i++) { + if (seals[i].publicKey === sealKey.public) { let crypto = new JSEncrypt(); crypto.setPrivateKey(sealKey.private); - return crypto.decrypt(seal.sealedKey); + return crypto.decrypt(seals[i].sealedKey); } } @@ -36,20 +40,23 @@ export function encryptChannelSubject(subject, publicKeys) { publicKeys.forEach(key => { crypto.setPublicKey(key); const sealedKey = crypto.encrypt(keyHex); - seals.push({ publicKey, sealedKey }); + seals.push({ key, sealedKey }); }); return { subjectEncrypted, subjectIv, seals }; } -export function decryptChannelSubject(subject, sealKey) { - const { subjectEncrypted, subjectIv, seals } = JSON.parse(subject); - const contentKey = getContentKey(seals, sealKey); +export function decryptChannelSubject(subject, contentKey) { + const { subjectEncrypted, subjectIv } = JSON.parse(subject); const iv = CryptoJS.enc.Hex.parse(subjectIv); const key = CryptoJS.enc.Hex.parse(contentKey); const enc = CryptoJS.enc.Base64.parse(subjectEncrypted); const cipher = CryptoJS.lib.CipherParams.create({ ciphertext: enc, iv: iv }); const dec = CryptoJS.AES.decrypt(cipher, key, { iv: iv }); + const str = dec.toString(CryptoJS.enc.Utf8); + if (!str) { + return null; + } return JSON.parse(dec.toString(CryptoJS.enc.Utf8)); } diff --git a/net/web/src/context/useCardContext.hook.js b/net/web/src/context/useCardContext.hook.js index f2ce013e..21fb5fd0 100644 --- a/net/web/src/context/useCardContext.hook.js +++ b/net/web/src/context/useCardContext.hook.js @@ -84,7 +84,6 @@ export function useCardContext() { const revision = curRevision.current; const delta = await getCards(token, setRevision.current); for (let card of delta) { - if (card.data) { let cur = cards.current.get(card.id); if (cur == null) { @@ -172,7 +171,7 @@ export function useCardContext() { const syncCardArticles = async (card) => {} const syncCardChannels = async (card) => { - const { cardProfile, cardDetail } = card.data; + const { cardProfile, cardDetail, setNotifiedView, setNotifiedChannel } = card.data; const node = cardProfile.node; const token = `${cardProfile.guid}.${cardDetail.token}`; let delta; @@ -181,7 +180,6 @@ export function useCardContext() { delta = await getContactChannels(node, token); } else { - const { setNotifiedView, setNotifiedChannel } = card.data; delta = await getContactChannels(node, token, setNotifiedView, setNotifiedChannel); } for (let channel of delta) { @@ -197,7 +195,6 @@ export function useCardContext() { else { cur.data.channelDetail = await getContactChannelDetail(node, token, channel.id); } - cur.data.unsealedSubject = null; cur.data.detailRevision = channel.data.detailRevision; } if (cur.data.topicRevision !== channel.data.topicRevision) { @@ -207,7 +204,6 @@ export function useCardContext() { else { cur.data.channelSummary = await getContactChannelSummary(node, token, channel.id); } - cur.data.unsealedSummary = null; cur.data.topicRevision = channel.data.topicRevision; } cur.revision = channel.revision; @@ -278,26 +274,6 @@ export function useCardContext() { let node = cardProfile.node; await removeContactChannel(node, token, channelId); }, - unsealChannelSubject: async (cardId, channelId, unsealed, revision) => { - const card = cards.current.get(cardId); - const channel = card.channels.get(channelId); - if (channel.revision === revision) { - channel.data.unsealedSubject = unsealed; - card.channels.set(channelId, channel); - cards.current.set(cardId, card); - updateState({ cards: cards.current }); - } - }, - unsealChannelSummary: async (cardId, channelId, unsealed, revision) => { - const card = cards.current.get(cardId); - const channel = card.channels.get(channelId); - if (channel.revision === revision) { - channel.data.unsealedSummary = unsealed; - card.channels.set(channelId, channel); - cards.current.set(cardId, card); - updateState({ cards: cards.current }); - } - }, addTopic: async (cardId, channelId, type, message, files) => { let { cardProfile, cardDetail } = cards.current.get(cardId).data; let token = cardProfile.guid + '.' + cardDetail.token; diff --git a/net/web/src/context/useChannelContext.hook.js b/net/web/src/context/useChannelContext.hook.js index 83ba8246..cea23613 100644 --- a/net/web/src/context/useChannelContext.hook.js +++ b/net/web/src/context/useChannelContext.hook.js @@ -65,7 +65,6 @@ export function useChannelContext() { let detail = await getChannelDetail(token, channel.id); cur.data.channelDetail = detail; } - cur.data.unsealedSubject = null; cur.data.detailRevision = channel.data.detailRevision; } if (cur.data.topicRevision !== channel.data.topicRevision) { @@ -76,7 +75,6 @@ export function useChannelContext() { let summary = await getChannelSummary(token, channel.id); cur.data.channelSummary = summary; } - cur.data.unsealedSummary = null; cur.data.topicRevision = channel.data.topicRevision; } cur.revision = channel.revision; @@ -134,22 +132,6 @@ export function useChannelContext() { clearChannelCard: async (channelId, cardId) => { return await clearChannelCard(access.current, channelId, cardId); }, - unsealChannelSubject: async (channelId, unsealed, revision) => { - const channel = channels.current.get(channelId); - if (channel.revision === revision) { - channel.data.unsealedSubject = unsealed; - channels.current.set(channelId, channel); - updateState({ channels: channels.current }); - } - }, - unsealChannelSummary: async (channelId, unsealed, revision) => { - const channel = channels.current.get(channelId); - if (channel.revision === revision) { - channel.data.unsealedSummary = unsealed; - channels.current.set(channelId, channel); - updateState({ channels: channels.current }); - } - }, addTopic: async (channelId, type, message, files) => { if (files?.length) { const topicId = await addChannelTopic(access.current, channelId, null, null, null); diff --git a/net/web/src/context/useConversationContext.hook.js b/net/web/src/context/useConversationContext.hook.js index d97fc624..2b074102 100644 --- a/net/web/src/context/useConversationContext.hook.js +++ b/net/web/src/context/useConversationContext.hook.js @@ -9,6 +9,7 @@ export function useConversationContext() { offsync: false, topics: new Map(), channel: null, + topicRevision: null, }); const card = useContext(CardContext); @@ -231,7 +232,6 @@ export function useConversationContext() { cur.data.topicDetail = slot.data.topicDetail; cur.data.detailRevision = slot.data.detailRevision; } - cur.data.unsealedSubject = null; } cur.revision = topic.revision; topics.current.set(topic.id, cur); @@ -240,7 +240,7 @@ export function useConversationContext() { marker.current = delta.marker; setTopicRevision.current = topicRevision; - updateState({ offsync: false, topics: topics.current }); + updateState({ offsync: false, topicRevision: topicRevision, topics: topics.current }); } } catch (err) { @@ -311,14 +311,6 @@ export function useConversationContext() { const { cardId, channelId } = conversationId.current; return getTopicAssetUrl(cardId, channelId, topicId, assetId); }, - unsealTopicSubject: (topicId, unsealed) => { - const topic = topics.current.get(topicId); - if (topic) { - topic.data.unsealedSubject = unsealed; - topics.current.set(topicId, topic); - updateState({ topics: topics.current }); - } - }, loadMore: async () => { loadMore.current = true; await sync(); diff --git a/net/web/src/session/channels/Channels.jsx b/net/web/src/session/channels/Channels.jsx index ab4361a4..6926e567 100644 --- a/net/web/src/session/channels/Channels.jsx +++ b/net/web/src/session/channels/Channels.jsx @@ -55,8 +55,8 @@ export function Channels({ open, active }) { { state.channels.length > 0 && ( ( - + )} /> )} diff --git a/net/web/src/session/channels/channelItem/ChannelItem.jsx b/net/web/src/session/channels/channelItem/ChannelItem.jsx index 13c8ecc9..0d83ed55 100644 --- a/net/web/src/session/channels/channelItem/ChannelItem.jsx +++ b/net/web/src/session/channels/channelItem/ChannelItem.jsx @@ -2,33 +2,29 @@ import { Tooltip } from 'antd'; import { ChannelItemWrapper, Markup } from './ChannelItem.styled'; import { Logo } from 'logo/Logo'; import { UnlockOutlined, LockFilled } from '@ant-design/icons'; -import { useChannelItem } from './useChannelItem.hook'; -export function ChannelItem({ cardId, channelId, filter, openChannel, active }) { - - const { state } = useChannelItem(cardId, channelId, filter, active); +export function ChannelItem({ item, openChannel, active }) { return ( - openChannel(channelId, cardId)}> -
+ openChannel(item.channelId, item.cardId)}> +
- +
- { state.locked && !state.unlocked && ( + { item.locked && !item.unlocked && ( )} - { state.locked && state.unlocked && ( + { item.locked && item.unlocked && ( )} - { state.subject } + { item.subject }
-
{ state.message }
+
{ item.message }
- { state.updatedFlag && ( + { item.updatedFlag && ( diff --git a/net/web/src/session/channels/channelItem/useChannelItem.hook.js b/net/web/src/session/channels/channelItem/useChannelItem.hook.js deleted file mode 100644 index a7c9719d..00000000 --- a/net/web/src/session/channels/channelItem/useChannelItem.hook.js +++ /dev/null @@ -1,253 +0,0 @@ -import { useContext, useState, useEffect, useRef } from 'react'; -import { StoreContext } from 'context/StoreContext'; -import { ChannelContext } from 'context/ChannelContext'; -import { CardContext } from 'context/CardContext'; -import { AccountContext } from 'context/AccountContext'; -import { ProfileContext } from 'context/ProfileContext'; -import { getCardByGuid } from 'context/cardUtil'; - -export function useChannelItem(cardId, channelId, filter, active) { - - const [state, setState] = useState({ - set: false, - visible: false, - active: false, - locked: false, - unlocked: false, - updateFlag: false, - img: null, - logo: null, - subject: null, - message: null, - }); - - const card = useContext(CardContext); - const channel = useContext(ChannelContext); - const account = useContext(AccountContext); - const store = useContext(StoreContext); - const profile = useContext(ProfileContext); - - const updateState = (value) => { - setState((s) => ({ ...s, ...value })); - } - - const syncing = useRef(false); - const setCardId = useRef(); - const setChannelId = useRef(); - const setCardRevision = useRef(); - const setChannelRevision = useRef(); - const setSealKey = useRef(); - - const actions = { - }; - - useEffect(() => { - sync(); - // eslint-disable-next-line - }, [card.state, channel.state, store.state, account.state]); - - useEffect(() => { - if (cardId === active?.card && channelId === active?.channel) { - updateState({ active: true }); - } - else { - updateState({ active: false }); - } - }, [cardId, channelId, active]); - - useEffect(() => { - if (filter) { - if (state.subject) { - updateState({ visible: state.subject.toUpperCase().includes(filter) }); - } - else { - updateState({ visible: false }); - } - } - else { - updateState({ visible: true }); - } - }, [filter, state.subject]); - - const sync = async () => { - if (!syncing.current) { - syncing.current = true; - - if (cardId !== setCardId.current || channelId !== setChannelId.current) { - await setChannel(cardId, channelId); - syncing.current = false; - await sync(); - return; - } - if (cardId) { - const contact = card.state.cards.get(cardId); - if (contact?.revision !== setCardRevision.current) { - await setChannel(cardId, channelId); - syncing.current = false; - await sync(); - return; - } - const conversation = contact.channels.get(channelId); - if (conversation?.revision !== setChannelRevision.current) { - await setChannel(cardId, channelId); - syncing.current = false; - await sync(); - return; - } - } - else { - const conversation = channel.state.channels.get(channelId); - if (conversation?.revision !== setChannelRevision.current) { - await setChannel(cardId, channelId); - syncing.current = false; - await sync(); - return; - } - } - const key = account.state.sealKey; - if (key?.pulic !== setSealKey.current?.public || key?.private !== setSealKey.current?.private) { - await setChannel(cardId, channelId); - syncing.current = false; - await sync(); - return; - } - - syncing.current = false; - } - } - - const setChannel = (cardId, channelId) => { - if (cardId) { - const cardItem = card.state.cards.get(cardId); - const channelItem = cardItem?.channels?.get(channelId); - setChannelItem(cardItem, channelItem); - setCardRevision.current = cardItem?.revision; - setChannelRevision.current = channelItem?.revision; - } - else { - const channelItem = channel.state.channels.get(channelId); - setChannelItem(null, channelItem); - setChannelRevision.current = channelItem?.revision; - } - setSealKey.current = account.state.sealKey; - setChannelId.current = channelId; - setCardId.current = cardId; - }; - - const setChannelItem = (cardItem, channelItem) => { - - if (!channelItem) { - updateState({ set: false }); - return; - } - const chan = { set: true }; - - // set updated flag - const key = `${cardId}:${channelId}` - const login = store.state['login:timestamp']; - if (!chan.updated || !login || chan.updated < login) { - chan.updatedFlag = false; - } - else if (store.state[key] && store.state[key] === channelItem.revision) { - chan.updatedFlag = false; - } - else { - chan.updatedFlag = true; - } - - // extract member info - let memberCount = 0; - let names = []; - let img = null; - let logo = null; - if (cardItem) { - const profile = cardItem?.data?.cardProfile; - if (profile?.name) { - names.push(profile.name); - } - if (profile?.imageSet) { - img = null; - logo = card.actions.getCardImageUrl(cardId); - } - else { - img = 'avatar'; - logo = null; - } - memberCount++; - } - for (let guid of channelItem?.data?.channelDetail?.members) { - if (guid !== profile.state.identity.guid) { - const contact = getCardByGuid(card.state.cards, guid); - const profile = contact?.data?.cardProfile; - if (profile?.name) { - names.push(profile.name); - } - if (profile?.imageSet) { - img = null; - logo = card.actions.getCardImageUrl(contact.id); - } - else { - img = 'avatar'; - logo = null; - } - memberCount++; - } - } - - // set logo and label - if (memberCount === 0) { - chan.img = 'solution'; - chan.label = 'Notes'; - } - else if (memberCount === 1) { - chan.logo = logo; - chan.img = img; - chan.label = names.join(','); - } - else { - chan.img = 'appstore'; - chan.label = names.join(','); - } - - // set subject - const detail = channelItem.data?.channelDetail; - if (detail?.dataType === 'sealedchannel') { - // handle sealed subject - chan.locked = true; - chan.unlocked = false; - } - else if (detail?.dataType === 'superbasic') { - chan.locked = false; - chan.unlocked = true; - try { - const data = JSON.parse(detail.data); - chan.subject = data.subject; - } - catch(err) { - console.log(err); - } - } - if (chan.subject == null) { - chan.subject = chan.label; - } - - // set message - const topic = channel.data?.channelSummary?.lastTopic; - if (topic?.dataType === 'sealedtopic') { - // handle sealed topic - } - else if (topic?.dataType === 'superbasictopic') { - try { - const data = JSON.parse(topic.data); - chan.message = data.text; - } - catch(err) { - console.log(err); - } - } - - updateState({ ...chan }); - } - - return { state, actions }; -} diff --git a/net/web/src/session/channels/useChannels.hook.js b/net/web/src/session/channels/useChannels.hook.js index 25613d99..d8b8d7dc 100644 --- a/net/web/src/session/channels/useChannels.hook.js +++ b/net/web/src/session/channels/useChannels.hook.js @@ -1,17 +1,21 @@ -import { useContext, useState, useEffect } from 'react'; +import { useContext, useState, useRef, useEffect } from 'react'; import { StoreContext } from 'context/StoreContext'; import { ChannelContext } from 'context/ChannelContext'; import { CardContext } from 'context/CardContext'; import { AccountContext } from 'context/AccountContext'; import { ViewportContext } from 'context/ViewportContext'; +import { ProfileContext } from 'context/ProfileContext'; +import { getCardByGuid } from 'context/cardUtil'; +import { isUnsealed, getChannelSeals, getContentKey, decryptChannelSubject } from 'context/sealUtil'; export function useChannels() { + const [filter, setFilter] = useState(); + const [state, setState] = useState({ display: null, channels: [], sealable: false, - filter: null, busy: false, showAdd: false, @@ -20,16 +24,126 @@ export function useChannels() { seal: false, }); + const profile = useContext(ProfileContext); const card = useContext(CardContext); const channel = useContext(ChannelContext); const account = useContext(AccountContext); const store = useContext(StoreContext); const viewport = useContext(ViewportContext); + const channels = useRef(new Map()); + const updateState = (value) => { setState((s) => ({ ...s, ...value })); } + const syncChannelDetail = (item, cardValue, channelValue) => { + + // extract member info + let memberCount = 0; + let names = []; + let img = null; + let logo = null; + if (cardValue) { + const profile = cardValue?.data?.cardProfile; + if (profile?.name) { + names.push(profile.name); + } + if (profile?.imageSet) { + img = null; + logo = card.actions.getCardImageUrl(cardValue.data.profileRevision); + } + else { + img = 'avatar'; + logo = null; + } + memberCount++; + } + for (let guid of channelValue?.data?.channelDetail?.members) { + if (guid !== profile.state.identity.guid) { + const contact = getCardByGuid(card.state.cards, guid); + const profile = contact?.data?.cardProfile; + if (profile?.name) { + names.push(profile.name); + } + if (profile?.imageSet) { + img = null; + logo = card.actions.getCardImageUrl(contact.id); + } + else { + img = 'avatar'; + logo = null; + } + memberCount++; + } + } + + // set logo and label + if (memberCount === 0) { + item.img = 'solution'; + item.label = 'Notes'; + } + else if (memberCount === 1) { + item.logo = logo; + item.img = img; + item.label = names.join(','); + } + else { + item.img = 'appstore'; + item.label = names.join(','); + } + + // set subject + const detail = channelValue.data?.channelDetail; + if (detail?.dataType === 'sealed') { + item.locked = true; + try { + const { sealKey } = account.state; + const seals = getChannelSeals(detail.data); + if (isUnsealed(seals, sealKey)) { + item.unlocked = true; + if (!item.contentKey) { + item.contentKey = getContentKey(seals, sealKey); + } + const unsealed = decryptChannelSubject(detail.data, item.contentKey); + item.subject = unsealed?.subject; + } + else { + item.unlocked = false; + item.contentKey = null; + } + } + catch(err) { + console.log(err); + item.unlocked = false; + } + } + else if (detail?.dataType === 'superbasic') { + item.locked = false; + item.unlocked = true; + try { + const data = JSON.parse(detail.data); + item.subject = data.subject; + } + catch(err) { + console.log(err); + } + } + if (item.subject == null) { + item.subject = item.label; + } + + // set updated revision + item.detailRevision = channelValue.data.detailRevision; + } + + const syncChannelSummary = (item, channelValue) => { + item.updated = channelValue.data?.channelSummary?.lastTopic?.created; + + // set updated revision + item.topicRevision = channelValue.data.topicRevision; + }; + useEffect(() => { const { seal, sealKey } = account.state; if (seal?.publicKey && sealKey?.public && sealKey?.private && seal.publicKey === sealKey.public) { @@ -38,21 +152,69 @@ export function useChannels() { else { updateState({ seal: false, sealable: false }); } - }, [account]); + }, [account.state]); useEffect(() => { - const merged = []; + const login = store.state['login:timestamp']; + const conversations = new Map(); + const { sealKey } = account.state; card.state.cards.forEach((cardValue, cardId) => { cardValue.channels.forEach((channelValue, channelId) => { - const updated = channelValue.data?.channelSummary?.lastTopic?.created; - merged.push({ updated, cardId, channelId }); + const key = `${channelId}::${cardId}`; + const { detailRevision, topicRevision } = channelValue.data; + let item = channels.current.get(key); + if (!item) { + item = { cardId, channelId }; + } + if (item.detailRevision !== detailRevision || + item.sealKey !== sealKey) { + syncChannelDetail(item, cardValue, channelValue); + } + if (item.topicRevision !== topicRevision || + item.sealKey !== sealKey) { + syncChannelSummary(item, channelValue); + } + item.sealKey = sealKey; + const revision = store.state[key]; +console.log("> ", channelValue.id, topicRevision, revision); + if (login && item.updated && item.updated > login && topicRevision !== revision) { + item.updatedFlag = true; + } + else { + item.updatedFlag = false; + } + conversations.set(key, item); }); }); channel.state.channels.forEach((channelValue, channelId) => { - const updated = channelValue.data?.channelSummary?.lastTopic?.created; - merged.push({ updated, channelId }); + const key = `${channelId}::${undefined}`; + const { detailRevision, topicRevision } = channelValue.data; + let item = channels.current.get(key); + if (!item) { + item = { channelId }; + } + if (item.detailRevision !== detailRevision || + item.sealKey !== sealKey) { + syncChannelDetail(item, null, channelValue); + } + if (item.topicRevision !== topicRevision || + item.sealKey !== sealKey) { + syncChannelSummary(item, channelValue); + } + item.sealKey = sealKey; + const revision = store.state[key]; +console.log("> ", channelValue.id, topicRevision, revision); + if (login && item.updated && item.updated > login && topicRevision !== revision) { + item.updatedFlag = true; + } + else { + item.updatedFlag = false; + } + conversations.set(key, item); }); + channels.current = conversations; + const merged = Array.from(conversations.values()); merged.sort((a, b) => { const aUpdated = a.updated; const bUpdated = b.updated; @@ -65,10 +227,15 @@ export function useChannels() { return -1; }); - updateState({ channels: merged }); + const filtered = merged.filter((item) => { + const subject = item.subject?.toUpperCase(); + return !filter || subject?.includes(filter); + }); + + updateState({ channels: filtered }); // eslint-disable-next-line - }, [channel, card]); + }, [account.state, store.state, card.state, channel.state, filter]); useEffect(() => { updateState({ display: viewport.state.display }); diff --git a/net/web/src/session/conversation/addTopic/AddTopic.jsx b/net/web/src/session/conversation/addTopic/AddTopic.jsx index 4a0c7f6a..351fab38 100644 --- a/net/web/src/session/conversation/addTopic/AddTopic.jsx +++ b/net/web/src/session/conversation/addTopic/AddTopic.jsx @@ -10,6 +10,7 @@ import { Carousel } from 'carousel/Carousel'; export function AddTopic({ cardId, channelId, sealed, sealKey }) { + const [modal, modalContext] = Modal.useModal(); const { state, actions } = useAddTopic(cardId, channelId); const attachImage = useRef(null); const attachAudio = useRef(null); @@ -30,7 +31,7 @@ export function AddTopic({ cardId, channelId, sealed, sealKey }) { } catch (err) { console.log(err); - Modal.error({ + modal.error({ title: 'Failed to Post Message', content: 'Please try again.', }); @@ -90,6 +91,7 @@ export function AddTopic({ cardId, channelId, sealed, sealKey }) { return ( + { modalContext } onSelectImage(e)} style={{display: 'none'}}/> onSelectAudio(e)} style={{display: 'none'}}/> onSelectVideo(e)} style={{display: 'none'}}/> diff --git a/net/web/src/session/conversation/useConversation.hook.js b/net/web/src/session/conversation/useConversation.hook.js index 894f8aab..73482c14 100644 --- a/net/web/src/session/conversation/useConversation.hook.js +++ b/net/web/src/session/conversation/useConversation.hook.js @@ -116,7 +116,7 @@ export function useConversation(cardId, channelId) { } const { error, loadingInit, loadingMore, subject, logoUrl, logoImg } = conversation.state; updateState({ topics, error, loadingInit, loadingMore, subject, logoUrl, logoImg }); - store.actions.setValue(`${channelId}::${cardId}`, Number(conversation.state.revision)); + store.actions.setValue(`${channelId}::${cardId}`, Number(conversation.state.topicRevision)); // eslint-disable-next-line }, [conversation]); diff --git a/net/web/test/Channel.test.js b/net/web/test/Channel.test.js index 4e7b23cb..bf390dc6 100644 --- a/net/web/test/Channel.test.js +++ b/net/web/test/Channel.test.js @@ -18,8 +18,6 @@ function ChannelView() { rendered.push(
- { entry.data.unsealedSubject } - { entry.data.unsealedSummary } { entry.data.channelDetail.data } { entry.data.channelSummary.data }
); @@ -232,16 +230,6 @@ test('add, update and remove channel', async () => { expect(screen.getByTestId('channels').attributes.count.value).toBe(count.toString()); }); - await act( async () => { - await channelContext.actions.unsealChannelSubject('123', 'unsealedsubject', 3); - await channelContext.actions.unsealChannelSummary('123', 'unsealedsummary', 3); - }); - - await waitFor(async () => { - expect(screen.getByTestId('unsealed-subject').textContent).toBe('unsealedsubject'); - expect(screen.getByTestId('unsealed-summary').textContent).toBe('unsealedsummary'); - }); - fetchChannels = [ { id: '123', revision: 3 } ]; await act( async () => { diff --git a/net/web/test/Conversation.test.js b/net/web/test/Conversation.test.js index 342af15c..0f49e0dc 100644 --- a/net/web/test/Conversation.test.js +++ b/net/web/test/Conversation.test.js @@ -84,15 +84,16 @@ beforeEach(() => { beginSet = false; const mockFetch = jest.fn().mockImplementation((url, options) => { + const params = url.split('/'); - if (params[2].startsWith('channels?agent')) { + if (params[2]?.startsWith('channels?agent')) { return Promise.resolve({ url: 'getChannels', status: statusChannels, json: () => Promise.resolve(fetchChannels), }); } - if (params[2].startsWith('channels?contact')) { + else if (params[4]?.startsWith('channels?contact')) { return Promise.resolve({ url: 'getCardChannels', status: statusCardChannels,