diff --git a/net/web/src/Api/getContactChannelTopic.js b/net/web/src/Api/getContactChannelTopic.js index 2a0696a2..9b921ee0 100644 --- a/net/web/src/Api/getContactChannelTopic.js +++ b/net/web/src/Api/getContactChannelTopic.js @@ -1,7 +1,7 @@ import { checkResponse, fetchWithTimeout } from './fetchUtil'; -export async function getContactChannelTopic(token, channelId, topicId) { - let topic = await fetchWithTimeout(`/content/channels/${channelId}/topics/${topicId}/detail?contact=${token}`, +export async function getContactChannelTopic(server, token, channelId, topicId) { + let topic = await fetchWithTimeout(`https://${server}/content/channels/${channelId}/topics/${topicId}/detail?contact=${token}`, { method: 'GET' }); checkResponse(topic) return await topic.json() diff --git a/net/web/src/Api/getContactChannelTopics.js b/net/web/src/Api/getContactChannelTopics.js index ca7dc9af..597abf48 100644 --- a/net/web/src/Api/getContactChannelTopics.js +++ b/net/web/src/Api/getContactChannelTopics.js @@ -1,11 +1,11 @@ import { checkResponse, fetchWithTimeout } from './fetchUtil'; -export async function getContactChannelTopics(token, channelId, revision) { +export async function getContactChannelTopics(server, token, channelId, revision) { let rev = '' if (revision != null) { rev = `&revision=${revision}` } - let topics = await fetchWithTimeout(`/content/channels/${channelId}/topics?contact=${token}${rev}`, + let topics = await fetchWithTimeout(`https://${server}/content/channels/${channelId}/topics?contact=${token}${rev}`, { method: 'GET' }); checkResponse(topics) return await topics.json() diff --git a/net/web/src/AppContext/useAppContext.hook.js b/net/web/src/AppContext/useAppContext.hook.js index 651fa91a..561c666c 100644 --- a/net/web/src/AppContext/useAppContext.hook.js +++ b/net/web/src/AppContext/useAppContext.hook.js @@ -1,10 +1,5 @@ import { useEffect, useState, useRef, useContext } from 'react'; -import { getContactProfile, setCardProfile, getCards, getCardImageUrl, getCardProfile, getCardDetail, getListingImageUrl, getListing, getAvailable, getUsername, setLogin, createAccount } from './fetchUtil'; -import { getChannels } from '../Api/getChannels'; -import { getChannel } from '../Api/getChannel'; -import { getContactChannels } from '../Api/getContactChannels'; -import { getContactChannel } from '../Api/getContactChannel'; - +import { getAvailable, getUsername, setLogin, createAccount } from './fetchUtil'; import { AccountContext } from './AccountContext'; import { ProfileContext } from './ProfileContext'; import { ArticleContext } from './ArticleContext'; @@ -12,146 +7,6 @@ import { GroupContext } from './GroupContext'; import { CardContext } from './CardContext'; import { ChannelContext } from './ChannelContext'; -async function updateChannels(token, revision, channelMap, mergeChannels) { - let channels = await getChannels(token, revision); - for (let channel of channels) { - if (channel.data) { - let cur = channelMap.get(channel.id); - if (cur == null) { - cur = { id: channel.id, data: { } } - } - if (cur.data.detailRevision != channel.data.detailRevision) { - if (channel.data.channelDetail != null) { - cur.data.channelDetail = channel.data.channelDetail; - cur.data.detailRevision = channel.data.detailRevision; - } - else { - let slot = await getChannel(token, channel.id); - cur.data.channelDetail = slot.data.channelDetail; - cur.data.detailRevision = slot.data.detailRevision; - } - } - cur.data.topicRevision = channel.data.topicRevision; - cur.revision = channel.revision; - channelMap.set(channel.id, cur); - } - else { - channelMap.delete(channel.id); - } - } - mergeChannels(); -} - -async function updateCards(token, revision, cardMap, updateData, mergeChannels) { - - let cards = await getCards(token, revision); - for (let card of cards) { - if (card.data) { - let cur = cardMap.get(card.id); - if (cur == null) { - cur = { id: card.id, data: { articles: new Map() }, channels: new Map() } - } - if (cur.data.detailRevision != card.data.detailRevision) { - if (card.data.cardDetail != null) { - cur.data.cardDetail = card.data.cardDetail; - } - else { - cur.data.cardDetail = await getCardDetail(token, card.id); - } - mergeChannels(); - cur.data.detailRevision = card.data.detailRevision; - } - if (cur.data.profileRevision != card.data.profileRevision) { - if (card.data.cardProfile != null) { - cur.data.cardProfile = card.data.cardProfile; - } - else { - cur.data.cardProfile = await getCardProfile(token, card.id); - } - cur.data.profileRevision = card.data.profileRevision; - } - const { cardDetail, cardProfile } = cur.data; - if (cardDetail.status === 'connected') { - if (cur.data.profileRevision != card.data.notifiedProfile) { - let message = await getContactProfile(cardProfile.node, cardProfile.guid, cardDetail.token); - await setCardProfile(token, card.id, message); - - // update remote profile - cur.data.notifiedProfile = card.data.notifiedProfile; - } - if (cur.data.notifiedView != card.data.notifiedView) { - // update remote articles and channels - cur.data.articles = new Map(); - cur.channels = new Map(); - - let contactToken = cur.data.cardProfile.guid + "." + cur.data.cardDetail.token - await updateContactChannels(contactToken, cur.data.notifiedView, cur.dataNotifiedChannel, cur.channels); - await updateContactArticles(contactToken, cur.data.notifiedView, cur.dataNotifiedArticle, cur.data.articles); - - // update view - cur.data.notifiedArticle = card.data.notifiedArticle; - cur.data.notifiedChannel = card.data.notifiedChannel; - cur.data.notifiedView = card.data.notifiedView; - mergeChannels(); - } - if (cur.data.notifiedArticle != card.data.notifiedArticle) { - // update remote articles - let contactToken = cur.data.cardProfile.guid + "." + cur.data.cardDetail.token - await updateContactArticles(contactToken, cur.data.notifiedView, cur.dataNotifiedArticle, cur.data.articles); - cur.data.notifiedArticle = card.data.notifiedArticle; - } - if (cur.data.notifiedChannel != card.data.notifiedChannel) { - // update remote channels - let contactToken = cur.data.cardProfile.guid + "." + cur.data.cardDetail.token - await updateContactChannels(contactToken, cur.data.notifiedView, cur.dataNotifiedChannel, cur.channels); - cur.data.notifiedChannel = card.data.notifiedChannel; - mergeChannels(); - } - } - cur.revision = card.revision; - cardMap.set(card.id, cur); - } - else { - cardMap.delete(card.id); - mergeChannels(); - } - } - updateData({ cards: Array.from(cardMap.values()) }); -} - -async function updateContactChannels(token, viewRevision, channelRevision, channelMap) { - let channels = await getContactChannels(token, viewRevision, channelRevision); - for (let channel of channels) { - if (channel.data) { - let cur = channelMap.get(channel.id); - if (cur == null) { - cur = { id: channel.id, data: { } } - } - if (cur.data.detailRevision != channel.data.detailRevision) { - if (channel.data.channelDetail != null) { - cur.data.channelDetail = channel.data.channelDetail; - cur.data.detailRevision = channel.data.detailRevision; - } - else { - let slot = await getContactChannel(token, channel.id); - cur.data.channelDetail = slot.data.channelDetail; - cur.data.detailRevision = slot.data.detailRevision; - } - } - cur.data.topicRevision = channel.data.topicRevision; - cur.revision = channel.revision; - channelMap.set(channel.id, cur); - } - else { - channelMap.delete(channel.id); - } - } -} - -async function updateContactArticles(token, viewRevision, articleRevision, articleMap) { - console.log("update contact attributes"); -} - async function appCreate(username, password, updateState, setWebsocket) { await createAccount(username, password); let access = await setLogin(username, password) @@ -177,15 +32,10 @@ export function useAppContext() { const [state, setState] = useState(null); const [appRevision, setAppRevision] = useState(); - const cardRevision = useRef(null); - const channelRevision = useRef(null); - - const channels = useRef(new Map()); - const cards = useRef(new Map()); const delay = useRef(2); - const ws = useRef(null); const revision = useRef(null); + const updateState = (value) => { setState((s) => ({ ...s, ...value })) } @@ -203,46 +53,8 @@ export function useAppContext() { const groupContext = useContext(GroupContext); const articleContext = useContext(ArticleContext); - const mergeChannels = () => { - let merged = []; - cards.current.forEach((value, key, map) => { - if (value?.data?.cardDetail?.status === 'connected') { - value.channels.forEach((slot, key, map) => { - merged.push({ guid: value?.data?.cardProfile?.guid, cardId: value?.id, channel: slot }); - }); - } - }); - channels.current.forEach((value, key, map) => { - merged.push({ channel: value }); - }); - updateData({ channels: merged }); - } - - const getCardByGuid = (guid) => { - let card = null; - cards.current.forEach((value, key, map) => { - if(value?.data?.cardProfile?.guid == guid) { - card = value - } - }); - return card; - } - - const getConnectedCards = () => { - let connected = [] - cards.current.forEach((value, key, map) => { - if(value?.data?.cardDetail?.status === 'connected') { - connected.push(value); - } - }); - return connected; - } - const resetData = () => { revision.current = null; - cardRevision.current = null; - channels.current = new Map(); - cards.current = new Map(); setState({}); } @@ -251,13 +63,6 @@ export function useAppContext() { appLogout(updateState, clearWebsocket); resetData(); }, - getRegistry: async (node) => getListing(node), - getRegistryImageUrl: (server, guid, revision) => getListingImageUrl(server, guid, revision), - getCardImageUrl: (cardId, revision) => getCardImageUrl(state.token, cardId, revision), - getCardByGuid: getCardByGuid, - getCard: (id) => cards.current.get(id), - getChannel: (id) => channels.current.get(id), - getConnectedCards: getConnectedCards, } const adminActions = { @@ -289,29 +94,6 @@ export function useAppContext() { } }, [appRevision]); - const processRevision = async (token) => { - while(revision.current != null) { - let rev = revision.current; - - // update card if revision changed - if (rev.card != cardRevision.current) { - await updateCards(token, cardRevision.current, cards.current, updateData, mergeChannels); - cardRevision.current = rev.card - } - - // update channel if revision changed - if (rev.channel != channelRevision.current) { - await updateChannels(token, channelRevision.current, channels.current, mergeChannels); - channelRevision.current = rev.channel - } - - // check if new revision was received during processing - if (rev == revision.current) { - revision.current = null - } - } - } - const setWebsocket = (token) => { accountContext.actions.setToken(token); @@ -324,15 +106,8 @@ export function useAppContext() { ws.current = new WebSocket("wss://" + window.location.host + "/status"); ws.current.onmessage = (ev) => { try { - if (revision.current != null) { - revision.current = JSON.parse(ev.data); - } - else { - let rev = JSON.parse(ev.data); - revision.current = rev; - processRevision(token); - setAppRevision(rev); - } + let rev = JSON.parse(ev.data); + setAppRevision(rev); } catch (err) { console.log(err); diff --git a/net/web/src/AppContext/useCardContext.hook.js b/net/web/src/AppContext/useCardContext.hook.js index d3f288b9..089fe163 100644 --- a/net/web/src/AppContext/useCardContext.hook.js +++ b/net/web/src/AppContext/useCardContext.hook.js @@ -13,6 +13,8 @@ import { getCardOpenMessage } from '../Api/getCardOpenMessage'; import { setCardOpenMessage } from '../Api/setCardOpenMessage'; import { getCardCloseMessage } from '../Api/getCardCloseMessage'; import { setCardCloseMessage } from '../Api/setCardCloseMessage'; +import { getContactChannelTopics } from '../Api/getContactChannelTopics'; +import { getContactChannelTopic } from '../Api/getContactChannelTopic'; import { addCard } from '../Api/addCard'; import { removeCard } from '../Api/removeCard'; @@ -69,8 +71,8 @@ export function useCardContext() { cur.data.articles = new Map(); cur.channels = new Map(); - await updateContactChannels(card.id, cur.data.cardProfile.guid, cur.data.cardDetail.token, cur.data.notifiedView, cur.dataNotifiedChannel, cur.channels); - await updateContactArticles(card.id, cur.data.cardProfile.guid, cur.data.cardDetail.token, cur.data.notifiedView, cur.dataNotifiedArticle, cur.data.articles); + await updateContactChannels(card.id, cur.data.cardProfile.guid, cur.data.cardDetail.token, cur.data.notifiedView, cur.data.notifiedChannel, cur.channels); + await updateContactArticles(card.id, cur.data.cardProfile.guid, cur.data.cardDetail.token, cur.data.notifiedView, cur.data.notifiedArticle, cur.data.articles); // update view cur.data.notifiedArticle = card.data.notifiedArticle; @@ -79,16 +81,19 @@ export function useCardContext() { } if (cur.data.notifiedArticle != card.data.notifiedArticle) { // update remote articles - await updateContactArticles(card.id, cur.data.cardProfile.guid, cur.data.cardDetail.token, cur.data.notifiedView, cur.dataNotifiedArticle, cur.data.articles); + await updateContactArticles(card.id, cur.data.cardProfile.guid, cur.data.cardDetail.token, cur.data.notifiedView, cur.data.notifiedArticle, cur.data.articles); cur.data.notifiedArticle = card.data.notifiedArticle; } if (cur.data.notifiedChannel != card.data.notifiedChannel) { // update remote channels - await updateContactChannels(card.id, cur.data.cardProfile.guid, cur.data.cardDetail.token, cur.data.notifiedView, cur.dataNotifiedChannel, cur.channels); +console.log("UPDATE CHANNEL: ", cur.data.notifiedChannel, card.data.notifiedChannel); + + await updateContactChannels(card.id, cur.data.cardProfile.guid, cur.data.cardDetail.token, cur.data.notifiedView, cur.data.notifiedChannel, cur.channels); cur.data.notifiedChannel = card.data.notifiedChannel; } } cur.revision = card.revision; +console.log("SAVE:", cur.data.notifiedChannel); cards.current.set(card.id, cur); } else { @@ -98,6 +103,8 @@ export function useCardContext() { } const updateContactChannels = async (cardId, guid, token, viewRevision, channelRevision, channelMap) => { +console.log("UPDATE CONTACT CHANNELS: ", viewRevision, channelRevision); + let delta = await getContactChannels(guid + "." + token, viewRevision, channelRevision); for (let channel of delta) { if (channel.data) { @@ -132,12 +139,15 @@ export function useCardContext() { const setCards = async (rev) => { if (next.current == null) { - await updateCards(); - updateState({ cards: cards.current }); - revision.current = rev; - if (next.current != null) { - let r = next.current; - next.current = null; + next.current = rev; + if (revision.current != rev) { + await updateCards(); + updateState({ cards: cards.current }); + revision.current = rev; + } + let r = next.current; + next.current = null; + if (revision.current != r) { setCards(r); } } @@ -164,13 +174,35 @@ export function useCardContext() { setCards(rev); }, getCardByGuid: getCardByGuid, - getImageUrl: (cardId, rev) => getCardImageUrl(access.current, cardId, rev), + getImageUrl: (cardId) => { + let { data } = cards.current.get(cardId); + return getCardImageUrl(access.current, cardId, data.profileRevision) + }, addChannelTopic: async (cardId, channelId, message, assets) => { let { cardProfile, cardDetail } = cards.current.get(cardId).data; let token = cardProfile.guid + '.' + cardDetail.token; let node = cardProfile.node; await addContactChannelTopic(node, token, channelId, message, assets); }, + getChannelRevision: (cardId, channelId) => { + let card = cards.current.get(cardId); + let channel = card.channels.get(channelId); + return channel.revision; + }, + getChannelTopics: async (cardId, channelId, revision) => { + let card = cards.current.get(cardId); + let node = card.data.cardProfile.node; + let channel = card.channels.get(channelId); + let token = card.data.cardProfile.guid + '.' + card.data.cardDetail.token; + return await getContactChannelTopics(node, token, channelId, revision); + }, + getChannelTopic: async (cardId, channelId, topicId) => { + let card = cards.current.get(cardId); + let node = card.data.cardProfile.node; + let channel = card.channels.get(channelId); + let token = card.data.cardProfile.guid + '.' + card.data.cardDetail.token; + return await getContactChannelTopic(node, token, channelId, topicId); + }, addCard: async (message) => { return await addCard(access.current, message); }, diff --git a/net/web/src/AppContext/useChannelContext.hook.js b/net/web/src/AppContext/useChannelContext.hook.js index d783d657..4e57dddf 100644 --- a/net/web/src/AppContext/useChannelContext.hook.js +++ b/net/web/src/AppContext/useChannelContext.hook.js @@ -3,6 +3,8 @@ import { getChannels } from '../Api/getChannels'; import { getChannel } from '../Api/getChannel'; import { addChannel } from '../Api/addChannel'; import { addChannelTopic } from '../Api/addChannelTopic'; +import { getChannelTopics } from '../Api/getChannelTopics'; +import { getChannelTopic } from '../Api/getChannelTopic'; export function useChannelContext() { const [state, setState] = useState({ @@ -31,7 +33,7 @@ export function useChannelContext() { cur.data.detailRevision = channel.data.detailRevision; } else { - let slot = await getChannel(state.token, channel.id); + let slot = await getChannel(access.current, channel.id); cur.data.channelDetail = slot.data.channelDetail; cur.data.detailRevision = slot.data.detailRevision; } @@ -48,14 +50,15 @@ export function useChannelContext() { const setChannels = async (rev) => { if (next.current == null) { + next.current = rev; if (revision.current != rev) { await updateChannels(); updateState({ channels: channels.current }); revision.current = rev; } - if (next.current != null) { - let r = next.current; - next.current = null; + let r = next.current; + next.current = null; + if (revision.current != r) { setChannels(r); } } @@ -77,6 +80,16 @@ export function useChannelContext() { addChannelTopic: async (channelId, message, assets) => { await addChannelTopic(access.current, channelId, message, assets); }, + getChannelRevision: (channelId) => { + let channel = channels.current.get(channelId); + return channel.revision; + }, + getChannelTopics: async (channelId, revision) => { + return await getChannelTopics(access.current, channelId, revision); + }, + getChannelTopic: async (channelId, topicId) => { + return await getChannelTopic(access.current, channelId, topicId); + }, } return { state, actions } diff --git a/net/web/src/User/Contact/useContact.hook.js b/net/web/src/User/Contact/useContact.hook.js index bd091904..8b0119ac 100644 --- a/net/web/src/User/Contact/useContact.hook.js +++ b/net/web/src/User/Contact/useContact.hook.js @@ -159,7 +159,7 @@ export function useContact() { updateState({ location: profile.location }); updateState({ node: profile.node }); if (contact.data.cardProfile.imageSet) { - updateState({ imageUrl: card.actions.getImageUrl(contact.id, contact.revision) }); + updateState({ imageUrl: card.actions.getImageUrl(contact.id) }); } else { updateState({ imageUrl: '' }); diff --git a/net/web/src/User/Conversation/AddTopic/AddTopic.styled.js b/net/web/src/User/Conversation/AddTopic/AddTopic.styled.js index af586f5c..fff8fdd6 100644 --- a/net/web/src/User/Conversation/AddTopic/AddTopic.styled.js +++ b/net/web/src/User/Conversation/AddTopic/AddTopic.styled.js @@ -42,8 +42,9 @@ export const AddTopicWrapper = styled.div` `; export const BusySpin = styled(Spin)` + display: flex; position: absolute; - margin-right: 12px; + padding-right: 12px; x-index: 10; `; diff --git a/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js b/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js index f4f21c95..98d49809 100644 --- a/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js +++ b/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js @@ -1,12 +1,10 @@ import { useContext, useState, useEffect, useRef } from 'react'; -import { AppContext } from '../../../AppContext/AppContext'; import { ConversationContext } from '../../../ConversationContext/ConversationContext'; export function useTopicItem() { const [state, setState] = useState({}); - const app = useContext(AppContext); const conversation = useContext(ConversationContext); const updateState = (value) => { diff --git a/net/web/src/User/Conversation/useConversation.hook.js b/net/web/src/User/Conversation/useConversation.hook.js index bbbf1f2f..43b3b455 100644 --- a/net/web/src/User/Conversation/useConversation.hook.js +++ b/net/web/src/User/Conversation/useConversation.hook.js @@ -1,11 +1,8 @@ import { useContext, useState, useEffect, useRef } from 'react'; -import { AppContext } from '../../AppContext/AppContext'; import { useNavigate, useLocation, useParams } from "react-router-dom"; -import { getChannelTopics } from '../../Api/getChannelTopics'; -import { getChannelTopic } from '../../Api/getChannelTopic'; -import { getContactChannelTopics } from '../../Api/getContactChannelTopics'; -import { getContactChannelTopic } from '../../Api/getContactChannelTopic'; import { ConversationContext } from '../../ConversationContext/ConversationContext'; +import { CardContext } from '../../AppContext/CardContext'; +import { ChannelContext } from '../../AppContext/ChannelContext'; export function useConversation() { @@ -15,11 +12,11 @@ export function useConversation() { const { cardId, channelId } = useParams(); const navigate = useNavigate(); - const app = useContext(AppContext); + const card = useContext(CardContext); + const channel = useContext(ChannelContext); const conversation = useContext(ConversationContext); const topics = useRef(new Map()); - -console.log("PARAMS: ", cardId, channelId); + const revision = useRef(null); const updateState = (value) => { setState((s) => ({ ...s, ...value })); @@ -33,86 +30,79 @@ console.log("PARAMS: ", cardId, channelId); const updateConversation = async () => { if (cardId) { - if(app?.actions?.getCard) { - let contact = app.actions.getCard(cardId); - let conversation = contact.channels.get(channelId); - if (conversation?.revision != state.revision) { - let token = contact.data.cardProfile.guid + "." + contact.data.cardDetail.token; - let slots = await getContactChannelTopics(token, channelId, state.revision); - for (let topic of slots) { - if (topic.data == null) { - topics.current.delete(topic.id); - } - else { - let cur = topics.current.get(topic.id); - if (cur == null) { - cur = { id: topic.id, data: {} }; - } - if (topic.data.detailRevision != cur.data.detailRevision) { - if(topic.data.topicDetail != null) { - cur.data.topicDetail = topic.data.topicDetail; - cur.data.detailRevision = topic.data.detailRevision; - } - else { - let slot = await getContactChannelTopic(token, channelId, topic.id); - cur.data.topicDetail = slot.data.topicDetail; - cur.data.detailRevision = slot.data.detailRevision; - } - } - cur.revision = topic.revision; - topics.current.set(topic.id, cur); - } + let rev = card.actions.getChannelRevision(cardId, channelId); + if (revision.current != rev) { + let delta = await card.actions.getChannelTopics(cardId, channelId, revision.current); + for (let topic of delta) { + if (topic.data == null) { + topics.current.delete(topic.id); + } + else { + let cur = topics.current.get(topic.id); + if (cur == null) { + cur = { id: topic.id, data: {} }; + } + if (topic.data.detailRevision != cur.data.detailRevision) { + if(topic.data.topicDetail != null) { + cur.data.topicDetail = topic.data.topicDetail; + cur.data.detailRevision = topic.data.detailRevision; + } + else { + let slot = await card.actions.getChannelTopic(cardId, channelId, topic.id); + cur.data.topicDetail = slot.data.topicDetail; + cur.data.detailRevision = slot.data.detailRevision; + } + } + cur.revision = topic.revision; + topics.current.set(topic.id, cur); } - - updateState({ - topics: Array.from(topics.current.values()), - revision: conversation.revision, - }); } + updateState({ + topics: Array.from(topics.current.values()), + }); + revision.current = rev; } } else { - if(app?.actions?.getChannel) { - let conversation = app.actions.getChannel(channelId); - if (conversation?.revision != state.revision) { - let slots = await getChannelTopics(app.state.token, channelId, state.revision); - - for (let topic of slots) { - if (topic.data == null) { - topics.current.delete(topic.id); - } - else { - let cur = topics.current.get(topic.id); - if (cur == null) { - cur = { id: topic.id, data: {} }; - } - if (topic.data.detailRevision != cur.data.detailRevision) { - if(topic.data.topicDetail != null) { - cur.data.topicDetail = topic.data.topicDetail; - cur.data.detailRevision = topic.data.detailRevision; - } - else { - let slot = await getChannelTopic(app.state.token, channelId, topic.id); - cur.data.topicDetail = slot.data.topicDetail; - cur.data.detailRevision = slot.data.detailRevision; - } - } - cur.revision = topic.revision; - topics.current.set(topic.id, cur); - } + let rev = channel.actions.getChannelRevision(channelId); + if (revision.current != rev) { + let delta = await channel.actions.getChannelTopics(channelId, revision.current); + for (let topic of delta) { + if (topic.data == null) { + topics.current.delete(topic.id); + } + else { + let cur = topics.current.get(topic.id); + if (cur == null) { + cur = { id: topic.id, data: {} }; + } + if (topic.data.detailRevision != cur.data.detailRevision) { + if(topic.data.topicDetail != null) { + cur.data.topicDetail = topic.data.topicDetail; + cur.data.detailRevision = topic.data.detailRevision; + } + else { + let slot = await channel.actions.getChannelTopic(channelId, topic.id); + cur.data.topicDetail = slot.data.topicDetail; + cur.data.detailRevision = slot.data.detailRevision; + } + } + cur.revision = topic.revision; + topics.current.set(topic.id, cur); } - updateState({ - topics: Array.from(topics.current.values()), - revision: conversation.revision - }); } + updateState({ + topics: Array.from(topics.current.values()), + revision: conversation.revision + }); + revision.current = rev; } } } useEffect(() => { updateConversation(); - }, [app]); + }, [card, channel]); return { state, actions }; } diff --git a/net/web/src/User/SideBar/Contacts/Cards/Cards.jsx b/net/web/src/User/SideBar/Contacts/Cards/Cards.jsx index 22d093dc..25b76e6c 100644 --- a/net/web/src/User/SideBar/Contacts/Cards/Cards.jsx +++ b/net/web/src/User/SideBar/Contacts/Cards/Cards.jsx @@ -25,7 +25,7 @@ export function Cards({ showRegistry }) { const cardImage = (item) => { if (actions?.getImageUrl) { - return actions.getImageUrl(item.id, item.revision); + return actions.getImageUrl(item.id); } return null } diff --git a/net/web/src/User/SideBar/Contacts/useContacts.hook.js b/net/web/src/User/SideBar/Contacts/useContacts.hook.js index 7ae38064..bd17d0c0 100644 --- a/net/web/src/User/SideBar/Contacts/useContacts.hook.js +++ b/net/web/src/User/SideBar/Contacts/useContacts.hook.js @@ -1,5 +1,4 @@ import { useContext, useState, useEffect } from 'react'; -import { AppContext } from '../../../AppContext/AppContext'; export function useContacts() { @@ -7,13 +6,9 @@ export function useContacts() { const actions = {}; - const app = useContext(AppContext); - const updateState = (value) => { setState((s) => ({ ...s, ...value })); } - useEffect(() => {}, [app]) - return { state, actions }; } diff --git a/net/web/src/VirtualList/VirtualList.jsx b/net/web/src/VirtualList/VirtualList.jsx index 80f2eb7e..bb4b3a8b 100644 --- a/net/web/src/VirtualList/VirtualList.jsx +++ b/net/web/src/VirtualList/VirtualList.jsx @@ -169,7 +169,7 @@ export function VirtualList({ items, itemRenderer }) { } } else { - let pos = containers.current[0].top + containers.current[0].height; + let pos = containers.current[0].top + containers.current[0].height + 2 * GUTTER; for (let i = 1; i < containers.current.length; i++) { if (containers.current[i].top != pos) { containers.current[i].top = pos;