support switching conversation without close

This commit is contained in:
Roland Osborne 2022-04-26 12:19:18 -07:00
parent 77bbb4cadc
commit d6963d1978
3 changed files with 55 additions and 9 deletions

View File

@ -7,6 +7,8 @@ import { ChannelContext } from 'context/ChannelContext';
export function useConversation() {
const [state, setState] = useState({
cardId: null,
channelId: null,
topics: [],
});
@ -17,6 +19,7 @@ export function useConversation() {
const conversation = useContext(ConversationContext);
const topics = useRef(new Map());
const revision = useRef(null);
const id = useRef({});
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));
@ -101,10 +104,27 @@ export function useConversation() {
}
useEffect(() => {
if (card.state.init && channel.state.init) {
updateConversation();
if (id.current.channelId != channelId || id.current.cardId) {
id.current = { cardId, channelId };
topics.current = new Map();
revision.current = null;
updateState({ cardId, channelId, topics: [] });
}
}, [card, channel]);
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]);
return { state, actions };
}

View File

@ -2,7 +2,7 @@ import React, { useRef, useState, useEffect } from 'react';
import { VirtualListWrapper, VirtualItem } from './VirtualList.styled';
import ReactResizeDetector from 'react-resize-detector';
export function VirtualList({ items, itemRenderer }) {
export function VirtualList({ id, items, itemRenderer }) {
const REDZONE = 256; // recenter on canvas if in canvas edge redzone
const HOLDZONE = 512; // drop slots outside of holdzone of view
@ -21,6 +21,7 @@ export function VirtualList({ items, itemRenderer }) {
let containers = useRef([]);
let anchorBottom = useRef(true);
let listRef = useRef();
let view = useRef(null);
const addSlot = (id, slot) => {
setSlots((m) => { m.set(id, slot); return new Map(m); })
@ -34,6 +35,10 @@ export function VirtualList({ items, itemRenderer }) {
setSlots((m) => { m.delete(id); return new Map(m); })
}
const clearSlots = () => {
setSlots((m) => { new Map() })
}
const growCanvasHeight = (val) => {
setCanvasHeight((h) => {
if (val > h) {
@ -51,8 +56,17 @@ export function VirtualList({ items, itemRenderer }) {
}, [viewHeight]);
useEffect(() => {
if (view.current != id) {
view.current = id;
latch.current = true;
containers.current = [];
anchorBottom.current = true;
scrollTop.current = 0;
listRef.current.scrollTo({ top: scrollTop.current, left: 0 });
clearSlots();
}
setItems();
}, [items]);
}, [items, id]);
useEffect(() => {
if (latch.current) {

View File

@ -91,6 +91,10 @@ export function useCardContext() {
cur.data.notifiedChannel = card.data.notifiedChannel;
}
}
else {
cur.channels = new Map();
cur.articles = new Map();
}
cur.revision = card.revision;
cards.current.set(card.id, cur);
}
@ -137,7 +141,12 @@ export function useCardContext() {
if (next.current == null) {
next.current = rev;
if (revision.current != rev) {
await updateCards();
try {
await updateCards();
}
catch(err) {
console.log(err);
}
updateState({ init: true, cards: cards.current });
revision.current = rev;
}
@ -171,8 +180,11 @@ export function useCardContext() {
},
getCardByGuid: getCardByGuid,
getImageUrl: (cardId) => {
let { data } = cards.current.get(cardId);
return getCardImageUrl(access.current, cardId, data.profileRevision)
let card = cards.current.get(cardId);
if (!card) {
return null;
}
return getCardImageUrl(access.current, cardId, card.data.profileRevision)
},
addChannelTopic: async (cardId, channelId, message, assets) => {
let { cardProfile, cardDetail } = cards.current.get(cardId).data;
@ -183,7 +195,7 @@ export function useCardContext() {
getChannelRevision: (cardId, channelId) => {
let card = cards.current.get(cardId);
let channel = card.channels.get(channelId);
return channel.revision;
return channel?.revision;
},
getChannelTopics: async (cardId, channelId, revision) => {
let card = cards.current.get(cardId);