databag/app/mobile/src/context/useChannelContext.hook.js

149 lines
5.2 KiB
JavaScript
Raw Normal View History

2022-09-15 08:03:20 +00:00
import { useState, useRef, useContext } from 'react';
import { StoreContext } from 'context/StoreContext';
import { getChannels } from 'api/getChannels';
import { getChannelDetail } from 'api/getChannelDetail';
import { getChannelSummary } from 'api/getChannelSummary';
export function useChannelContext() {
const [state, setState] = useState({
2022-09-19 23:02:55 +00:00
channels: new Map(),
2022-09-15 08:03:20 +00:00
});
const store = useContext(StoreContext);
const session = useRef(null);
const curRevision = useRef(null);
const setRevision = useRef(null);
const syncing = useRef(false);
2022-09-19 23:02:55 +00:00
const channels = useRef(new Map());
2022-09-15 08:03:20 +00:00
const updateState = (value) => {
setState((s) => ({ ...s, ...value }))
}
2022-09-20 07:50:53 +00:00
const setChannel = (channelId, channel) => {
channels.current.set(channelId, {
channelId: channel?.id,
revision: channel?.revision,
detail: channel?.data?.channelDetail,
summary: channel?.data?.channelSummary,
detailRevision: channel?.data?.detailRevision,
topicRevision: channel?.data?.topicRevision,
});
}
const setChannelDetails = (channelId, detail, revision) => {
2022-09-20 05:39:53 +00:00
let channel = channels.current.get(channelId);
if (channel?.data) {
2022-09-20 07:50:53 +00:00
channel.detail = detail;
channel.detailRevision = revision;
2022-09-20 05:39:53 +00:00
channels.current.set(channelId, channel);
}
}
const setChannelSummary = (channelId, summary, revision) => {
let channel = channels.current.get(channelId);
2022-09-20 07:50:53 +00:00
if (channel) {
channel.summary = summary;
channel.topicRevision = revision;
2022-09-20 05:39:53 +00:00
channels.curent.set(channelId, channel);
}
}
const setChannelRevision = (channelId, revision) => {
let channel = channels.current.get(channelId);
if (channel) {
channel.revision = revision;
channels.current.set(channelId, channel);
}
}
2022-09-15 08:03:20 +00:00
const sync = async () => {
if (!syncing.current && setRevision.current !== curRevision.current) {
syncing.current = true;
try {
const revision = curRevision.current;
const { server, appToken, guid } = session.current;
const delta = await getChannels(server, appToken, setRevision.current);
for (let channel of delta) {
if (channel.data) {
if (channel.data.channelDetail && channel.data.channelSummary) {
await store.actions.setChannelItem(guid, channel);
2022-09-20 07:50:53 +00:00
setChannel(channel.id, channel);
2022-09-15 08:03:20 +00:00
}
else {
const { detailRevision, topicRevision, channelDetail, channelSummary } = channel.data;
const view = await store.actions.getChannelItemView(guid, channel.id);
2022-09-15 22:12:06 +00:00
if (view == null) {
console.log('alert: expected channel not synced');
let assembled = JSON.parse(JSON.stringify(channel));
assembled.data.channelDetail = await getChannelDetail(server, appToken, channel.id);
assembled.data.channelSummary = await getChannelSummary(server, appToken, channel.id);
await store.actions.setChannelItem(guid, assembled);
2022-09-20 07:50:53 +00:00
setChannel(assembled.id, assembled);
2022-09-15 08:03:20 +00:00
}
2022-09-15 22:12:06 +00:00
else {
if (view.detailRevision != detailRevision) {
const detail = await getChannelDetail(server, appToken, channel.id);
await store.actions.setChannelItemDetail(guid, channel.id, detailRevision, detail);
2022-09-20 05:39:53 +00:00
setChannelDetail(channel.id, detail, detailRevision);
2022-09-15 22:12:06 +00:00
}
if (view.topicRevision != topicRevision) {
const summary = await getChannelSummary(server, appToken, channel.id);
await store.actions.setChannelItemSummary(guid, channel.id, topicRevision, summary);
2022-09-20 05:39:53 +00:00
setChannelSummary(channel.id, summary, topicRevision);
2022-09-15 22:12:06 +00:00
}
2022-09-20 05:39:53 +00:00
await store.actions.setChannelItemRevision(guid, channel.id, channel.revision);
setChannelRevision(channel.id, channel.revision);
2022-09-15 08:03:20 +00:00
}
}
}
else {
2022-09-15 18:26:03 +00:00
await store.actions.clearChannelItem(guid, channel.id);
2022-09-20 05:39:53 +00:00
channels.current.delete(channel.id);
2022-09-15 08:03:20 +00:00
}
}
setRevision.current = revision;
await store.actions.setChannelRevision(guid, revision);
2022-09-20 05:39:53 +00:00
updateState({ channels: channels.current });
2022-09-15 08:03:20 +00:00
}
catch(err) {
console.log(err);
syncing.current = false;
return;
}
syncing.current = false;
sync();
}
};
const actions = {
setSession: async (access) => {
const { guid, server, appToken } = access;
2022-09-19 23:02:55 +00:00
channels.current = new Map();
const items = await store.actions.getChannelItems(guid);
for(item of items) {
channels.current.set(item.channelId, item);
}
2022-09-15 08:03:20 +00:00
const revision = await store.actions.getChannelRevision(guid);
2022-09-19 23:02:55 +00:00
updateState({ channels: channels.current });
2022-09-15 08:03:20 +00:00
setRevision.current = revision;
curRevision.current = revision;
session.current = access;
},
clearSession: () => {
session.current = {};
2022-09-19 23:02:55 +00:00
channels.current = new Map();
updateState({ account: null, channels: channels.current });
2022-09-15 08:03:20 +00:00
},
setRevision: (rev) => {
curRevision.current = rev;
sync();
},
}
return { state, actions }
}