diff --git a/net/web/src/App.js b/net/web/src/App.js index 4988967c..a5ddbf82 100644 --- a/net/web/src/App.js +++ b/net/web/src/App.js @@ -6,7 +6,7 @@ import { ArticleContextProvider } from 'context/ArticleContext'; import { GroupContextProvider } from 'context/GroupContext'; import { CardContextProvider } from 'context/CardContext'; import { ChannelContextProvider } from 'context/ChannelContext'; -import { ConversationContextProvider } from './ConversationContext/ConversationContext'; +import { ConversationContextProvider } from 'context/ConversationContext'; import { Home } from './Home/Home'; import { Login } from './Login/Login'; import { Create } from './Create/Create'; diff --git a/net/web/src/ConversationContext/useConversationContext.hook.js b/net/web/src/ConversationContext/useConversationContext.hook.js deleted file mode 100644 index 1078ed77..00000000 --- a/net/web/src/ConversationContext/useConversationContext.hook.js +++ /dev/null @@ -1,19 +0,0 @@ -import { useEffect, useState, useRef } from 'react'; - -export function useConversationContext() { - const [state, setState] = useState({}); - - useEffect(() => { - }, []); - - const updateState = (value) => { - setState((s) => ({ ...s, ...value })) - } - - const actions = { - } - - return { state, actions } -} - - diff --git a/net/web/src/User/Conversation/Conversation.jsx b/net/web/src/User/Conversation/Conversation.jsx index 2510fd8b..8b32929c 100644 --- a/net/web/src/User/Conversation/Conversation.jsx +++ b/net/web/src/User/Conversation/Conversation.jsx @@ -1,5 +1,4 @@ import React, { useState, useEffect, useRef } from 'react' -import { ConversationContextProvider } from '../../ConversationContext/ConversationContext'; import { CloseOutlined, UserOutlined } from '@ant-design/icons'; import { useConversation } from './useConversation.hook'; import { Button, Checkbox, Modal, Spin } from 'antd' diff --git a/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js b/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js index 98d49809..3f5a20e2 100644 --- a/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js +++ b/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js @@ -1,5 +1,5 @@ import { useContext, useState, useEffect, useRef } from 'react'; -import { ConversationContext } from '../../../ConversationContext/ConversationContext'; +import { ConversationContext } from 'context/ConversationContext'; export function useTopicItem() { diff --git a/net/web/src/User/Conversation/useConversation.hook.js b/net/web/src/User/Conversation/useConversation.hook.js index b913993a..af6dc6d4 100644 --- a/net/web/src/User/Conversation/useConversation.hook.js +++ b/net/web/src/User/Conversation/useConversation.hook.js @@ -1,13 +1,13 @@ import { useContext, useState, useEffect, useRef } from 'react'; import { useNavigate, useLocation, useParams } from "react-router-dom"; -import { ConversationContext } from '../../ConversationContext/ConversationContext'; +import { ConversationContext } from 'context/ConversationContext'; import { CardContext } from 'context/CardContext'; import { ChannelContext } from 'context/ChannelContext'; export function useConversation() { const [state, setState] = useState({ - init: false, + init: true, cardId: null, channelId: null, topics: [], @@ -15,12 +15,7 @@ export function useConversation() { const { cardId, channelId } = useParams(); const navigate = useNavigate(); - const card = useContext(CardContext); - const channel = useContext(ChannelContext); const conversation = useContext(ConversationContext); - const topics = useRef(new Map()); - const revision = useRef(null); - const id = useRef({}); const updateState = (value) => { setState((s) => ({ ...s, ...value })); @@ -32,101 +27,17 @@ export function useConversation() { }, }; - const updateConversation = async () => { - if (cardId) { - 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({ - init: true, - topics: Array.from(topics.current.values()), - }); - revision.current = rev; - } - } - else { - 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({ - init: true, - topics: Array.from(topics.current.values()), - }); - revision.current = rev; - } - } - } + useEffect(() => { + conversation.actions.setConversationId(cardId, channelId); + updateState({ cardId, channelId }); + }, [cardId, channelId]); useEffect(() => { - if (id.current.channelId != channelId || id.current.cardId != cardId) { - id.current = { cardId, channelId }; - topics.current = new Map(); - revision.current = null; - updateState({ init: false, cardId, channelId, topics: [] }); - } - if (card.state.init && channel.state.init) { - if (cardId) { - if(card.state.cards.get(cardId)?.data.cardDetail.status != 'connected') { - window.alert("You are no longer connected to the host"); - navigate('/user') - } - } - try { - updateConversation(); - } - catch (err) { - console.log(err); - } - } - }, [card, channel, cardId, channelId]); + updateState({ + init: conversation.state.init, + topics: Array.from(conversation.state.topics.values()), + }); + }, [conversation]); return { state, actions }; } diff --git a/net/web/src/ConversationContext/ConversationContext.js b/net/web/src/context/ConversationContext.js similarity index 100% rename from net/web/src/ConversationContext/ConversationContext.js rename to net/web/src/context/ConversationContext.js diff --git a/net/web/src/context/useConversationContext.hook.js b/net/web/src/context/useConversationContext.hook.js new file mode 100644 index 00000000..c6d8b72e --- /dev/null +++ b/net/web/src/context/useConversationContext.hook.js @@ -0,0 +1,137 @@ +import { useEffect, useState, useRef, useContext } from 'react'; +import { CardContext } from 'context/CardContext'; +import { ChannelContext } from 'context/ChannelContext'; + +export function useConversationContext() { + + const [state, setState] = useState({ + init: false, + topics: new Map(), + }); + + const card = useContext(CardContext); + const channel = useContext(ChannelContext); + const topics = useRef(new Map()); + const revision = useRef(null); + const conversationId = useRef(null); + + const updateState = (value) => { + setState((s) => ({ ...s, ...value })); + } + + const setTopics = async () => { + const { cardId, channelId } = conversationId.current; + + if (cardId) { + 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({ + init: true, + topics: topics.current, + }); + revision.current = rev; + } + } + else { + 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({ + init: true, + topics: topics.current, + }); + revision.current = rev; + } + } + } + + const updateConversation = async () => { + + if (!card.state.init || !channel.state.init) { + return; + } + + const { cardId } = conversationId.current; + if (cardId && card.state.cards.get(cardId)?.data.cardDetail.status != 'connected') { + window.alert("You are disconnected from the host"); + conversationId.current = null; + return; + } + + try { + setTopics(); + } + catch (err) { + console.log(err); + } + }; + + useEffect(() => { + if (conversationId.current != null) { + updateConversation(); + } + }, [card, channel]); + + const actions = { + setConversationId: (cardId, channelId) => { + conversationId.current = { cardId, channelId }; + revision.current = null; + topics.current = new Map(); + updateState({ init: false, topics: topics.current }); + updateConversation(); + } + } + + return { state, actions } +} + +