2022-09-15 08:03:20 +00:00
|
|
|
import { useState, useRef, useContext } from 'react';
|
|
|
|
import { StoreContext } from 'context/StoreContext';
|
2022-10-07 05:52:28 +00:00
|
|
|
import { UploadContext } from 'context/UploadContext';
|
2022-09-15 08:03:20 +00:00
|
|
|
import { getChannels } from 'api/getChannels';
|
|
|
|
import { getChannelDetail } from 'api/getChannelDetail';
|
|
|
|
import { getChannelSummary } from 'api/getChannelSummary';
|
2022-09-29 18:31:55 +00:00
|
|
|
import { addChannel } from 'api/addChannel';
|
|
|
|
import { removeChannel } from 'api/removeChannel';
|
|
|
|
import { removeChannelTopic } from 'api/removeChannelTopic';
|
|
|
|
import { setChannelTopicSubject } from 'api/setChannelTopicSubject';
|
|
|
|
import { addChannelTopic } from 'api/addChannelTopic';
|
|
|
|
import { getChannelTopics } from 'api/getChannelTopics';
|
|
|
|
import { getChannelTopic } from 'api/getChannelTopic';
|
|
|
|
import { getChannelTopicAssetUrl } from 'api/getChannelTopicAssetUrl';
|
|
|
|
import { setChannelSubject } from 'api/setChannelSubject';
|
|
|
|
import { setChannelCard } from 'api/setChannelCard';
|
|
|
|
import { clearChannelCard } from 'api/clearChannelCard';
|
2022-09-15 08:03:20 +00:00
|
|
|
|
|
|
|
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);
|
2022-10-07 05:52:28 +00:00
|
|
|
const upload = useContext(UploadContext);
|
2022-09-15 08:03:20 +00:00
|
|
|
|
|
|
|
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) => {
|
2022-09-20 20:17:20 +00:00
|
|
|
let update = channels.current.get(channelId);
|
|
|
|
if (!update) {
|
|
|
|
update = { readRevision: 0 };
|
|
|
|
}
|
|
|
|
update.channelId = channel?.id;
|
|
|
|
update.revision = channel?.revision;
|
|
|
|
update.detail = channel?.data?.channelDetail;
|
|
|
|
update.summary = channel?.data?.channelSummary;
|
|
|
|
update.detailRevision = channel?.data?.detailRevision;
|
|
|
|
update.topicRevision = channel?.data?.topicRevision;
|
2022-09-20 22:19:12 +00:00
|
|
|
channels.current.set(channelId, update);
|
2022-09-20 07:50:53 +00:00
|
|
|
}
|
2022-10-10 06:26:32 +00:00
|
|
|
const setChannelDetail = (channelId, detail, revision) => {
|
2022-09-20 05:39:53 +00:00
|
|
|
let channel = channels.current.get(channelId);
|
2022-09-20 20:17:20 +00:00
|
|
|
if (channel) {
|
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 17:57:57 +00:00
|
|
|
channels.current.set(channelId, channel);
|
2022-09-20 05:39:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
const setChannelRevision = (channelId, revision) => {
|
|
|
|
let channel = channels.current.get(channelId);
|
|
|
|
if (channel) {
|
|
|
|
channel.revision = revision;
|
|
|
|
channels.current.set(channelId, channel);
|
|
|
|
}
|
|
|
|
}
|
2022-09-20 20:17:20 +00:00
|
|
|
const setChannelReadRevision = (channelId, revision) => {
|
|
|
|
let channel = channels.current.get(channelId);
|
|
|
|
if (channel) {
|
|
|
|
channel.readRevision = revision;
|
|
|
|
channels.current.set(channelId, channel);
|
|
|
|
}
|
|
|
|
}
|
2022-09-29 18:31:55 +00:00
|
|
|
const setChannelSyncRevision = (channelId, revision) => {
|
|
|
|
let channel = channels.current.get(channelId);
|
|
|
|
if (channel) {
|
|
|
|
channel.syncRevision = revision;
|
|
|
|
channels.current.set(channelId, channel);
|
|
|
|
}
|
|
|
|
}
|
2022-09-20 05:39:53 +00:00
|
|
|
|
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();
|
|
|
|
},
|
2022-09-20 20:17:20 +00:00
|
|
|
setReadRevision: async (channelId, rev) => {
|
|
|
|
await store.actions.setChannelItemReadRevision(session.current.guid, channelId, rev);
|
|
|
|
setChannelReadRevision(channelId, rev);
|
|
|
|
updateState({ channels: channels.current });
|
2022-09-29 06:30:22 +00:00
|
|
|
},
|
|
|
|
setSyncRevision: async (channelId, revision) => {
|
|
|
|
const { guid } = session.current;
|
2022-09-29 18:31:55 +00:00
|
|
|
await store.actions.setChannelItemSyncRevision(guid, channelId, revision);
|
|
|
|
setChannelSyncRevision(channelId, revision);
|
|
|
|
updateState({ channels: channels.current });
|
2022-09-29 06:30:22 +00:00
|
|
|
},
|
|
|
|
getTopicItems: async (channelId) => {
|
|
|
|
const { guid } = session.current;
|
|
|
|
return await store.actions.getChannelTopicItems(guid, channelId);
|
|
|
|
},
|
2022-09-29 23:00:48 +00:00
|
|
|
setTopicItem: async (channelId, topicId, topic) => {
|
2022-09-29 06:30:22 +00:00
|
|
|
const { guid } = session.current;
|
2022-09-29 23:00:48 +00:00
|
|
|
return await store.actions.setChannelTopicItem(guid, channelId, topicId, topic);
|
2022-09-29 06:30:22 +00:00
|
|
|
},
|
|
|
|
clearTopicItem: async (channelId, topicId) => {
|
|
|
|
const { guid } = session.current;
|
|
|
|
return await store.actions.clearChannelTopicItem(guid, channelId, topicId);
|
|
|
|
},
|
|
|
|
clearTopicItems: async (channelId) => {
|
|
|
|
const { guid } = session.current;
|
|
|
|
return await store.actions.clearChannelTopicItems(guid, channelId);
|
|
|
|
},
|
2022-09-29 18:31:55 +00:00
|
|
|
getTopic: async (channelId, topicId) => {
|
2022-09-29 22:21:18 +00:00
|
|
|
const { server, appToken } = session.current;
|
|
|
|
return await getChannelTopic(server, appToken, channelId, topicId);
|
2022-09-29 18:31:55 +00:00
|
|
|
},
|
2022-09-29 22:21:18 +00:00
|
|
|
getTopics: async (channelId, revision) => {
|
|
|
|
const { server, appToken } = session.current;
|
|
|
|
return await getChannelTopics(server, appToken, channelId, revision);
|
2022-09-29 18:31:55 +00:00
|
|
|
},
|
2022-09-29 22:21:18 +00:00
|
|
|
getTopicAssetUrl: (channelId, topicId, assetId) => {
|
|
|
|
const { server, appToken } = session.current;
|
|
|
|
return getChannelTopicAssetUrl(server, appToken, channelId, topicId, assetId);
|
2022-09-29 18:31:55 +00:00
|
|
|
},
|
2022-10-07 05:52:28 +00:00
|
|
|
addTopic: async (channelId, message, files) => {
|
2022-09-29 22:21:18 +00:00
|
|
|
const { server, appToken } = session.current;
|
2022-10-07 05:52:28 +00:00
|
|
|
if (files?.length > 0) {
|
|
|
|
const topicId = await addChannelTopic(server, appToken, channelId, null, null);
|
|
|
|
upload.actions.addTopic(server, appToken, channelId, topicId, files, async (assets) => {
|
|
|
|
message.assets = assets;
|
|
|
|
await setChannelTopicSubject(server, appToken, channelId, topicId, message);
|
|
|
|
}, async () => {
|
|
|
|
try {
|
|
|
|
await removeChannelTopic(server, appToken, channelId, topicId);
|
|
|
|
}
|
|
|
|
catch (err) {
|
|
|
|
console.log(err);
|
|
|
|
}
|
|
|
|
});
|
2022-10-06 22:34:29 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
await addChannelTopic(server, appToken, channelId, message, []);
|
|
|
|
}
|
2022-09-29 18:31:55 +00:00
|
|
|
},
|
|
|
|
setTopicSubject: async (channelId, topicId, data) => {
|
2022-09-29 22:21:18 +00:00
|
|
|
const { server, appToken } = session.current;
|
|
|
|
return await setChannelTopicSubject(server, appToken, channelId, topicId, data);
|
2022-09-29 18:31:55 +00:00
|
|
|
},
|
2022-10-10 06:26:32 +00:00
|
|
|
setSubject: async (channelId, data) => {
|
|
|
|
const { server, appToken } = session.current;
|
|
|
|
return await setChannelSubject(server, appToken, channelId, data);
|
|
|
|
},
|
2022-09-29 18:31:55 +00:00
|
|
|
remove: async (channelId) => {
|
2022-09-29 22:21:18 +00:00
|
|
|
const { server, appToken } = session.current;
|
|
|
|
return await removeChannel(server, appToken, channelId);
|
2022-09-29 18:31:55 +00:00
|
|
|
},
|
|
|
|
removeTopic: async (channelId, topicId) => {
|
2022-09-29 22:21:18 +00:00
|
|
|
const { server, appToken } = session.current;
|
|
|
|
return await removeChannelTopic(server, appToken, channelId, topicId);
|
2022-09-29 18:31:55 +00:00
|
|
|
},
|
2022-09-15 08:03:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return { state, actions }
|
|
|
|
}
|
|
|
|
|