syncing topics from server

This commit is contained in:
balzack 2022-09-29 22:34:31 -07:00
parent 40a29e17c3
commit 0251b648ef
2 changed files with 83 additions and 65 deletions

View File

@ -9,18 +9,18 @@ export function useConversationContext() {
subject: null,
logo: null,
contacts: [],
topics: [],
topics: new Map(),
});
const store = useContext(StoreContext);
const card = useContext(CardContext);
const channel = useContext(ChannelContext);
const profile = useContext(ProfileContext);
const topics = useRef(new Map());
const topics = useRef(null);
const revision = useRef(0);
const detailRevision = useRef(0);
const syncRevision = useRef(0);
const syncing = useRef(false);
const conversationId = useRef(null);
const reset = useRef(false);
const setView = useRef(0);
const updateState = (value) => {
@ -33,17 +33,11 @@ export function useConversationContext() {
}
return await channel.actions.getTopicItems(channelId);
}
const getTopicDeltaItems = async (cardId, channelId, revision) => {
const setTopicItem = async (cardId, channelId, topic) => {
if (cardId) {
return await card.actions.getChannelTopicDeltaItems(cardId, channelId, revision);
return await card.actions.setChannelTopicItem(cardId, channelId, topic);
}
return await channel.actions.getTopicDeltaItems(channelId, revision);
}
const setTopicItem = async (cardId, channelId, revision, topic) => {
if (cardId) {
return await card.actions.setChannelTopicItem(cardId, channelId, revision, topic);
}
return await channel.actions.setTopicItem(channelId, revision, topic);
return await channel.actions.setTopicItem(channelId, topic);
}
const clearTopicItem = async (cardId, channelId, topicId) => {
if (cardId) {
@ -93,55 +87,82 @@ export function useConversationContext() {
}
return await channel.actions.remvoeTopic(channelId, topicId);
}
const setSyncRevision = async (cardId, channelId, revision) => {
if (cardId) {
return await card.actions.setSyncRevision(cardId, channelId, revision);
}
return await channel.actions.setSyncRevision(channelId, revision);
}
const sync = async () => {
const curView = setView.current;
if (!syncing.current && conversationId.current) {
const { cardId, channelId } = conversationId.current;
const item = getChannel(cardId, channelId);
if (item && (item.revision !== revision.current || item.syncRevision != syncRevision.current)) {
syncing.current = true;
if (!syncing.current) {
if (reset.current) {
revision.current = null;
detailRevision.current = null;
topics.current = null;
reset.current = false;
}
if (conversationId.current) {
const { cardId, channelId } = conversationId.current;
const channelItem = getChannel(cardId, channelId);
if (channelItem && (channelItem.revision !== revision.current)) {
syncing.current = true;
try {
// set channel details
if (detailRevision.current != item.detailRevision) {
if (curView === setView.current) {
setChannel(item);
detailRevision.current = item.detailRevision;
try {
// set channel details
if (detailRevision.current != channelItem.detailRevision) {
if (curView === setView.current) {
setChannel(channelItem);
detailRevision.current = channelItem.detailRevision;
}
}
}
// set channel topics
if (syncRevision.current != item.syncRevision) {
if (syncRevision.current) {
const topics = await getTopicDeltaItems(cardId, channelId);
// initial load from store
if (!topics.current) {
topics.current = new Map();
const items = await getTopicItems(cardId, channelId);
items.forEach(item => {
topics.current.set(item.topicId, item);
});
}
else {
const topics = await getTopicItems(cardId, channelId);
// sync from server
if (channelItem.topicRevision !== channelItem.syncRevision) {
const res = await getTopics(cardId, channelId, channelItem.syncRevision)
for (const topic of res.topics) {
if (!topic.data) {
topics.current.delete(topic.id);
await clearTopicItem(cardId, channelId, topic.id);
}
const cached = topics.current.get(topic.id);
if (!cached || cached.detailRevision != topic.data.detailRevision) {
if (!topic.data.topicDetail) {
const updated = await getTopic(cardId, channelId, topic.id);
topic.data.topicDetail = updated.data.topicDetail;
}
await setTopicItem(cardId, channelId, topic);
const { id, revision, data } = topic;
topics.current.set(id, { topicId: id, revision: revision, detailRevision: topic.data.detailRevision, detail: topic.data.topicDetail });
}
}
await setSyncRevision(cardId, channelId, channelItem.topicRevision);
}
if (curView === setView.current) {
syncRevision.current = item.syncRevision;
// update revision
revision.current = channelItem.revision;
if (curView == setView.current) {
updateState({ topics: topics.current });
}
}
// sync from server to store
if (item.topicRevision !== item.syncRevision) {
const res = await getTopics(cardId, channelId, item.syncRevision)
syncing.current = false;
sync();
}
// update revision
if (curView === setView.current) {
revision.current = item.revision;
//TODO set to synced state
catch(err) {
console.log(err);
syncing.current = false;
//TODO set to unsynced state
}
syncing.current = false;
sync();
}
catch(err) {
console.log(err);
syncing.current = false;
//TODO set to unsynced state
}
}
}
@ -241,17 +262,14 @@ export function useConversationContext() {
if (channel == null) {
setView.current++;
conversationId.current = null;
updateState({ subject: null, logo: null, contacts: [], topics: [] });
reset.current = true;
updateState({ subject: null, logo: null, contacts: [], topics: new Map() });
}
else if (channel.cardId !== conversationId.current?.cardId || channel.channelId !== conversationId.current?.channelId) {
setView.current++;
conversationId.current = channel;
updateState({ subject: null, logo: null, contacts: [], topics: [] });
revision.current = null;
detailRevision.current = null;
syncRevision.current = null;
topics.current = new Map();
reset.current = true;
updateState({ subject: null, logo: null, contacts: [], topics: new Map() });
sync();
}
},

View File

@ -214,7 +214,7 @@ export function useStoreContext() {
readRevision: channel.read_revision,
detailRevision: channel.detail_revision,
topicRevision: channel.topic_revision,
syncRevsion: channel.sync_revision,
syncRevision: channel.sync_revision,
detail: decodeObject(channel.detail),
summary: decodeObject(channel.summary),
}));
@ -230,9 +230,9 @@ export function useStoreContext() {
detail: decodeObject(topic.detail),
}));
},
setChannelTopicItem: async (guid, channelId, topicId, topic) => {
const { id, revision, data } = channel;
await db.current.executeSql(`INSERT OR REPLACE INTO channel_topic_${guid} (channel_id, topic_id, revision, channel_revision, detail_revision, detail) values (?, ?, ?, ?, ?, ?);`, [channelId, id, revision, channelRevision, data.detailRevision, encodeObject(data.topicDetail)]);
setChannelTopicItem: async (guid, channelId, topic) => {
const { id, revision, data } = topic;
await db.current.executeSql(`INSERT OR REPLACE INTO channel_topic_${guid} (channel_id, topic_id, revision, detail_revision, detail) values (?, ?, ?, ?, ?);`, [channelId, id, revision, data.detailRevision, encodeObject(data.topicDetail)]);
},
clearChannelTopicItem: async (guid, channelId, topicId) => {
await db.current.executeSql(`DELETE FROM channel_topic_${guid} WHERE channel_id=? and topic_id=?`, [channelId, topicId]);
@ -302,15 +302,15 @@ export function useStoreContext() {
detail: decodeObject(topic.detail),
}));
},
setCardChannelTopicItem: async (guid, cardId, channelId, topicId, topic) => {
const { id, revision, data } = channel;
await db.current.executeSql(`INSERT OR REPLACE INTO channel_topic_${guid} (card_id, channel_id, topic_id, revision, channel_revision, detail_revision, detail) values (?, ?, ?, ?, ?, ?, ?);`, [cardId, channelId, id, revision, channelRevision, data.detailRevision, encodeObject(data.topicDetail)]);
setCardChannelTopicItem: async (guid, cardId, channelId, topic) => {
const { id, revision, data } = topic;
await db.current.executeSql(`INSERT OR REPLACE INTO card_channel_topic_${guid} (card_id, channel_id, topic_id, revision, detail_revision, detail) values (?, ?, ?, ?, ?, ?);`, [cardId, channelId, id, revision, data.detailRevision, encodeObject(data.topicDetail)]);
},
clearCardChannelTopicItem: async (guid, cardId, channelId, topicId) => {
await db.current.executeSql(`DELETE FROM channel_topic_${guid} WHERE card_id=? and channel_id=? and topic_id=?`, [cardId, channelId, topicId]);
await db.current.executeSql(`DELETE FROM card_channel_topic_${guid} WHERE card_id=? and channel_id=? and topic_id=?`, [cardId, channelId, topicId]);
},
clearCardChannelTopicItems: async (guid, cardId, channelId) => {
await db.current.executeSql(`DELETE FROM channel_topic_${guid} WHERE card_id=? and channel_id=?`, [cardId, channelId]);
await db.current.executeSql(`DELETE FROM card_channel_topic_${guid} WHERE card_id=? and channel_id=?`, [cardId, channelId]);
},
}