mirror of
https://github.com/balzack/databag.git
synced 2025-02-18 22:19:20 +00:00
refactoring conversation context in mobiel app
This commit is contained in:
parent
7e03cdcc97
commit
eca43835be
@ -82,12 +82,15 @@ export function useCardContext() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const setCardChannelField = (cardId, channelId, field, value) => {
|
const setCardChannelField = (cardId, channelId, field, value, field2, value2) => {
|
||||||
const card = cards.current.get(cardId);
|
const card = cards.current.get(cardId);
|
||||||
if (card) {
|
if (card) {
|
||||||
const channel = card.channels.get(channelId);
|
const channel = card.channels.get(channelId);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
channel[field] = value;
|
channel[field] = value;
|
||||||
|
if(field2) {
|
||||||
|
channel[field2] = value2;
|
||||||
|
}
|
||||||
card.channels.set(channelId, { ...channel });
|
card.channels.set(channelId, { ...channel });
|
||||||
cards.current.set(cardId, { ...card });
|
cards.current.set(cardId, { ...card });
|
||||||
}
|
}
|
||||||
@ -374,7 +377,7 @@ export function useCardContext() {
|
|||||||
getTopics: async (cardId, channelId, revision, count, begin, end) => {
|
getTopics: async (cardId, channelId, revision, count, begin, end) => {
|
||||||
const { detail, profile } = cards.current.get(cardId) || {};
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
const cardToken = `${profile?.guid}.${detail?.token}`;
|
const cardToken = `${profile?.guid}.${detail?.token}`;
|
||||||
return await store.actions.getCardChannelTopicItems(guid, cardId, channelId);
|
return await getContactChannelTopics(profile?.node, cardToken, channelId);
|
||||||
},
|
},
|
||||||
getChannelTopic: async (cardId, channelId, topicId) => {
|
getChannelTopic: async (cardId, channelId, topicId) => {
|
||||||
const { detail, profile } = cards.current.get(cardId) || {};
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
@ -401,6 +404,11 @@ export function useCardContext() {
|
|||||||
await store.actions.setCardChannelItemTopicMarker(guid, cardId, channelId, marker);
|
await store.actions.setCardChannelItemTopicMarker(guid, cardId, channelId, marker);
|
||||||
setCardField(cardId, 'topicMarker', marker);
|
setCardField(cardId, 'topicMarker', marker);
|
||||||
},
|
},
|
||||||
|
setChannelMarkerAndSync: async (cardId, channelId, marker, revision) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
await store.actions.setCardChannelItemMarkerAndSync(guid, cardId, channelId, marker, revision);
|
||||||
|
setCardField(cardId, 'topicMarker', marker, 'syncRevision', revision);
|
||||||
|
},
|
||||||
setCardFlag: async (cardId) => {
|
setCardFlag: async (cardId) => {
|
||||||
const { guid } = acccess.current;
|
const { guid } = acccess.current;
|
||||||
await store.actions.setCardItemBlocked(guid, cardId);
|
await store.actions.setCardItemBlocked(guid, cardId);
|
||||||
@ -451,15 +459,15 @@ export function useCardContext() {
|
|||||||
const { guid } = access.current;
|
const { guid } = access.current;
|
||||||
return await store.actions.getCardChannelTopicItems(guid, cardId, channelId);
|
return await store.actions.getCardChannelTopicItems(guid, cardId, channelId);
|
||||||
},
|
},
|
||||||
setChannelTopicItem: async (cardId, channelId, topicId, topic) => {
|
setTopicItem: async (cardId, channelId, topicId, topic) => {
|
||||||
const { guid } = access.current;
|
const { guid } = access.current;
|
||||||
return await store.actions.setCardChannelTopicItem(guid, cardId, channelId, topicId, topic);
|
return await store.actions.setCardChannelTopicItem(guid, cardId, channelId, topicId, topic);
|
||||||
},
|
},
|
||||||
clearChannelTopicItem: async (cardId, channelId, topicId) => {
|
clearTopicItem: async (cardId, channelId, topicId) => {
|
||||||
const { guid } = access.current;
|
const { guid } = access.current;
|
||||||
return await store.actions.clearCardChannelTopicItem(guid, cardId, channelId, topicId);
|
return await store.actions.clearCardChannelTopicItem(guid, cardId, channelId, topicId);
|
||||||
},
|
},
|
||||||
clearChannelTopicItems: async (cardId, channelId) => {
|
clearTopicItems: async (cardId, channelId) => {
|
||||||
const { guid } = access.current;
|
const { guid } = access.current;
|
||||||
return await store.actions.clearCardChannelTopicItems(guid, cardId, channelId);
|
return await store.actions.clearCardChannelTopicItems(guid, cardId, channelId);
|
||||||
},
|
},
|
||||||
|
@ -47,9 +47,12 @@ export function useChannelContext() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const setChannelField = (channelId, field, value) => {
|
const setChannelField = (channelId, field, value, field2, value2) => {
|
||||||
const channel = channels.get(channelId) || {};
|
const channel = channels.get(channelId) || {};
|
||||||
channel[field] = value;
|
channel[field] = value;
|
||||||
|
if (field2) {
|
||||||
|
channel[field2] = value2;
|
||||||
|
}
|
||||||
channels.set(channelId, { ...channel });
|
channels.set(channelId, { ...channel });
|
||||||
updateState({ channels: channels.current });
|
updateState({ channels: channels.current });
|
||||||
};
|
};
|
||||||
@ -223,6 +226,11 @@ export function useChannelContext() {
|
|||||||
await store.actions.setChannelItemTopicMarker(guid, channelId, revision);
|
await store.actions.setChannelItemTopicMarker(guid, channelId, revision);
|
||||||
setChannelField(channelId, 'topicMarker', marker);
|
setChannelField(channelId, 'topicMarker', marker);
|
||||||
},
|
},
|
||||||
|
setMarkerAndSync: async (channelId, marker, revision) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
await store.actions.setChannelItemMarkerAndSync(guid, channelId, revision);
|
||||||
|
setChannelField(channelId, 'topicMarker', marker, 'syncRevision', revision);
|
||||||
|
},
|
||||||
setChannelFlag: async (channelId) => {
|
setChannelFlag: async (channelId) => {
|
||||||
const { guid } = access.current;
|
const { guid } = access.current;
|
||||||
await store.actions.setChannelItemBlocked(guid, channelId);
|
await store.actions.setChannelItemBlocked(guid, channelId);
|
||||||
@ -249,7 +257,7 @@ export function useChannelContext() {
|
|||||||
const { server, guid } = access.current;
|
const { server, guid } = access.current;
|
||||||
return await addFlag(server, guid, channelId, topicId);
|
return await addFlag(server, guid, channelId, topicId);
|
||||||
},
|
},
|
||||||
getTopicItems: async (channelId, revision, count, begin, end) => {
|
getTopicItems: async (channelId) => {
|
||||||
const { guid } = access.current;
|
const { guid } = access.current;
|
||||||
return await store.actions.getChannelTopicItems(guid, channelId);
|
return await store.actions.getChannelTopicItems(guid, channelId);
|
||||||
},
|
},
|
||||||
|
@ -8,670 +8,402 @@ import moment from 'moment';
|
|||||||
import CryptoJS from 'crypto-js';
|
import CryptoJS from 'crypto-js';
|
||||||
|
|
||||||
export function useConversationContext() {
|
export function useConversationContext() {
|
||||||
|
const COUNT = 64;
|
||||||
|
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
topic: null,
|
offsync: false,
|
||||||
subject: null,
|
|
||||||
logo: null,
|
|
||||||
revision: null,
|
|
||||||
contacts: [],
|
|
||||||
topics: new Map(),
|
topics: new Map(),
|
||||||
created: null,
|
card: null,
|
||||||
host: null,
|
channel: null,
|
||||||
init: false,
|
|
||||||
progress: null,
|
|
||||||
cardId: null,
|
|
||||||
channelId: null,
|
|
||||||
pushEnabled: null,
|
|
||||||
locked: false,
|
|
||||||
unlocked: false,
|
|
||||||
seals: null,
|
|
||||||
});
|
});
|
||||||
const store = useContext(StoreContext);
|
|
||||||
const upload = useContext(UploadContext);
|
|
||||||
const card = useContext(CardContext);
|
const card = useContext(CardContext);
|
||||||
const channel = useContext(ChannelContext);
|
const channel = useContext(ChannelContext);
|
||||||
const profile = useContext(ProfileContext);
|
|
||||||
const topics = useRef(null);
|
|
||||||
const revision = useRef(null);
|
|
||||||
const force = useRef(false);
|
|
||||||
const more = useRef(false);
|
|
||||||
const detailRevision = useRef(0);
|
|
||||||
const syncing = useRef(false);
|
|
||||||
const conversationId = useRef(null);
|
|
||||||
const reset = useRef(false);
|
const reset = useRef(false);
|
||||||
const setView = useRef(0);
|
const more = useRef(false);
|
||||||
const transfer = useRef(null);
|
const force = useRef(false);
|
||||||
|
const syncing = useRef(false);
|
||||||
|
const update = useRef(false);
|
||||||
|
|
||||||
|
const loaded = useRef(false);
|
||||||
|
const conversationId = useRef(null);
|
||||||
|
const topics = useRef(new Map());
|
||||||
|
|
||||||
const updateState = (value) => {
|
const updateState = (value) => {
|
||||||
setState((s) => ({ ...s, ...value }))
|
setState((s) => ({ ...s, ...value }))
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const { cardId, channelId } = state;
|
|
||||||
const key = cardId ? `${cardId}:${channelId}` : `:${channelId}`
|
|
||||||
const progress = upload.state.progress.get(key);
|
|
||||||
if (progress) {
|
|
||||||
let count = 0;
|
|
||||||
let complete = 0;
|
|
||||||
let active = 0;
|
|
||||||
let loaded = 0;
|
|
||||||
let total = 0;
|
|
||||||
let error = false;
|
|
||||||
progress.forEach(post => {
|
|
||||||
count += post.count;
|
|
||||||
complete += (post.index - 1);
|
|
||||||
if (post.active) {
|
|
||||||
active += 1;
|
|
||||||
loaded += post.active.loaded;
|
|
||||||
total += post.active.total;
|
|
||||||
}
|
|
||||||
if (post.error) {
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
percent = Math.floor(((((loaded / total) * active) + complete) / count) * 100);
|
|
||||||
if (transfer.current == null || error || Math.abs(transfer.current - percent) > 5) {
|
|
||||||
updateState({ progress: percent, uploadError: error });
|
|
||||||
transfer.current = percent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
setTimeout(() => {
|
|
||||||
upload.actions.clearErrors(cardId, channelId);
|
|
||||||
updateState({ progress: null, uploadError: false });
|
|
||||||
transfer.current = null;
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updateState({ progress: null });
|
|
||||||
transfer.current = null;
|
|
||||||
}
|
|
||||||
}, [upload, state.cardId, state.channelId]);
|
|
||||||
|
|
||||||
const getTopicItems = async (cardId, channelId) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.getChannelTopicItems(cardId, channelId);
|
|
||||||
}
|
|
||||||
return await channel.actions.getTopicItems(channelId);
|
|
||||||
}
|
|
||||||
const setTopicItem = async (cardId, channelId, topic) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.setChannelTopicItem(cardId, channelId, topic);
|
|
||||||
}
|
|
||||||
return await channel.actions.setTopicItem(channelId, topic);
|
|
||||||
}
|
|
||||||
const clearTopicItem = async (cardId, channelId, topicId) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.clearChannelTopicItem(cardId, channelId, topicId);
|
|
||||||
}
|
|
||||||
return await channel.actions.clearTopicItem(channelId, topicId);
|
|
||||||
}
|
|
||||||
const getTopic = async (cardId, channelId, topicId) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.getChannelTopic(cardId, channelId, topicId);
|
|
||||||
}
|
|
||||||
return await channel.actions.getTopic(channelId, topicId);
|
|
||||||
}
|
|
||||||
const getTopics = async (cardId, channelId, revision, begin, end) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.getChannelTopics(cardId, channelId, revision, 16, begin, end);
|
|
||||||
}
|
|
||||||
return await channel.actions.getTopics(channelId, revision, 16, begin, end)
|
|
||||||
}
|
|
||||||
const getTopicAssetUrl = (cardId, channelId, assetId) => {
|
|
||||||
if (cardId) {
|
|
||||||
return card.actions.getChannelTopicAssetUrl(cardId, channelId, topicId, assetId);
|
|
||||||
}
|
|
||||||
return channel.actions.getTopicAssetUrl(channelId, assetId);
|
|
||||||
}
|
|
||||||
const addTopic = async (cardId, channelId, message, asssets) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.addChannelTopic(cardId, channelId, message, assetId);
|
|
||||||
}
|
|
||||||
return await channel.actions.addTopic(channelId, message, assetId);
|
|
||||||
}
|
|
||||||
const setTopicSubject = async (cardId, channelId, topicId, dataType, data) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.setChannelTopicSubject(cardId, channelId, topicId, dataType, data);
|
|
||||||
}
|
|
||||||
return await channel.actions.setTopicSubject(channelId, topicId, dataType, data);
|
|
||||||
}
|
|
||||||
const remove = async (cardId, channelId) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.removeChannel(cardId, channelId);
|
|
||||||
}
|
|
||||||
return await channel.actions.remove(channelId);
|
|
||||||
}
|
|
||||||
const removeTopic = async (cardId, channelId, topicId) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.removeChannelTopic(cardId, channelId, topicId);
|
|
||||||
}
|
|
||||||
return await channel.actions.removeTopic(channelId, topicId);
|
|
||||||
}
|
|
||||||
const setNotifications = async (cardId, channelId, notify) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.setChannelNotifications(cardId, channelId, notify);
|
|
||||||
}
|
|
||||||
return await channel.actions.setNotifications(channelId, notify);
|
|
||||||
}
|
|
||||||
const getNotifications = async (cardId, channelId) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.getChannelNotifications(cardId, channelId);
|
|
||||||
}
|
|
||||||
return await channel.actions.getNotifications(channelId);
|
|
||||||
}
|
|
||||||
const setSyncRevision = async (cardId, channelId, revision) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.setSyncRevision(cardId, channelId, revision);
|
|
||||||
}
|
|
||||||
return await channel.actions.setSyncRevision(channelId, revision);
|
|
||||||
}
|
|
||||||
const setTopicMarker = async (cardId, channelId, marker) => {
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.setTopicMarker(cardId, channelId, marker);
|
|
||||||
}
|
|
||||||
return await channel.actions.setTopicMarker(channelId, marker);
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (conversationId.current) {
|
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
const channelItem = getChannel(cardId, channelId);
|
|
||||||
if (channelItem) {
|
|
||||||
setChannel(channelItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [card, channel]);
|
|
||||||
|
|
||||||
const sync = async () => {
|
const sync = async () => {
|
||||||
const curView = setView.current;
|
if (!syncing.current && (reset.current || update.current || force.current || more.current)) {
|
||||||
if (!syncing.current) {
|
|
||||||
if (reset.current) {
|
const loadMore = more.current;
|
||||||
revision.current = null;
|
const ignoreRevision = force.current;
|
||||||
detailRevision.current = null;
|
const conversation = converstaionId.current;
|
||||||
topics.current = null;
|
let curRevision, setRevision, marker;
|
||||||
reset.current = false;
|
|
||||||
}
|
|
||||||
if (conversationId.current) {
|
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
const channelItem = getChannel(cardId, channelId);
|
|
||||||
|
|
||||||
if (channelItem && (channelItem.revision !== revision.current || force.current || more.current)) {
|
|
||||||
syncing.current = true;
|
syncing.current = true;
|
||||||
|
update.current = false;
|
||||||
try {
|
|
||||||
|
|
||||||
// sync from server
|
|
||||||
let res;
|
|
||||||
if (!topics.current) {
|
|
||||||
topics.current = new Map();
|
|
||||||
const items = await getTopicItems(cardId, channelId);
|
|
||||||
items.forEach(item => {
|
|
||||||
topics.current.set(item.topicId, item);
|
|
||||||
});
|
|
||||||
await setChannel(channelItem);
|
|
||||||
detailRevision.current = channelItem.detailRevision;
|
|
||||||
}
|
|
||||||
else if (detailRevision.current != channelItem.detailRevision) {
|
|
||||||
await setChannel(channelItem);
|
|
||||||
detailRevision.current = channelItem.detailRevision;
|
|
||||||
}
|
|
||||||
else if (more.current) {
|
|
||||||
more.current = false;
|
|
||||||
res = await getTopics(cardId, channelId, null, null, channelItem.topicMarker)
|
|
||||||
}
|
|
||||||
else if (channelItem.topicRevision !== channelItem.syncRevision || force.current) {
|
|
||||||
force.current = false;
|
force.current = false;
|
||||||
res = await getTopics(cardId, channelId, channelItem.syncRevision, channelItem.topicMarker)
|
loadMore.current = false;
|
||||||
|
|
||||||
|
if (reset.current) {
|
||||||
|
reset.current = false;
|
||||||
|
loaded.current = false;
|
||||||
|
topics.current = new Map();
|
||||||
|
updateState({ offsync: false, channel: null, card: null, topics: topics.current });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conversation) {
|
||||||
|
const { cardId, channelId } = conversation;
|
||||||
|
|
||||||
|
if (loaded.current) {
|
||||||
|
const cardValue = cardId ? card.state.cards.get(cardId) : null;
|
||||||
|
const channelValue = cardId ? cardValue?.get(channelId) : channel.state.channels.get(channelId);
|
||||||
|
if (channelValue) {
|
||||||
|
const { topicRevision, syncRevision, topicMarker } = channelValue;
|
||||||
|
curRevision = topicRevision;
|
||||||
|
setRevision = syncRevision;
|
||||||
|
marker = topicMarker;
|
||||||
|
updateState({ card: cardValue, channel: channelValue });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (cardId) {
|
console.log("failed to load conversation");
|
||||||
card.actions.setChannelReadRevision(cardId, channelId, revision.current);
|
sysncing.current = false;
|
||||||
}
|
|
||||||
else {
|
|
||||||
channel.actions.setReadRevision(channelId, channelItem.revision);
|
|
||||||
}
|
|
||||||
revision.current = channelItem.revision;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res?.topics) {
|
|
||||||
for (const topic of res.topics) {
|
|
||||||
if (!topic.data) {
|
|
||||||
topics.current.delete(topic.id);
|
|
||||||
await clearTopicItem(cardId, channelId, topic.id);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
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 = updated.data;
|
|
||||||
}
|
|
||||||
if (!topic.data) {
|
|
||||||
topics.current.delete(topic.id);
|
|
||||||
await clearTopicItem(cardId, channelId, topic.id);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
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 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res?.marker) {
|
|
||||||
await setTopicMarker(cardId, channelId, res.marker);
|
|
||||||
}
|
|
||||||
if (res?.revision) {
|
|
||||||
await setSyncRevision(cardId, channelId, res.revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curView == setView.current) {
|
|
||||||
updateState({ topics: topics.current, init: true, error: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
syncing.current = false;
|
|
||||||
sync();
|
|
||||||
}
|
|
||||||
catch(err) {
|
|
||||||
console.log(err);
|
|
||||||
syncing.current = false;
|
|
||||||
updateState({ error: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getCard = (guid) => {
|
|
||||||
let contact = null
|
|
||||||
card.state.cards.forEach((card, cardId, map) => {
|
|
||||||
if (card?.profile?.guid === guid) {
|
|
||||||
contact = card;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return contact;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getChannel = (cardId, channelId) => {
|
|
||||||
if (cardId) {
|
|
||||||
const entry = card.state.cards.get(cardId);
|
|
||||||
return entry?.channels.get(channelId);
|
|
||||||
}
|
|
||||||
return channel.state.channels.get(channelId);
|
|
||||||
}
|
|
||||||
|
|
||||||
const setChannel = async (item) => {
|
|
||||||
let contacts = [];
|
|
||||||
let logo = null;
|
|
||||||
let topic = null;
|
|
||||||
let subject = null;
|
|
||||||
let locked = false;
|
|
||||||
let unlocked = false;
|
|
||||||
let seals = null;
|
|
||||||
|
|
||||||
let timestamp;
|
|
||||||
const date = new Date(item.detail.created * 1000);
|
|
||||||
const now = new Date();
|
|
||||||
const offset = now.getTime() - date.getTime();
|
|
||||||
if(offset < 86400000) {
|
|
||||||
timestamp = moment(date).format('h:mma');
|
|
||||||
}
|
|
||||||
else if (offset < 31449600000) {
|
|
||||||
timestamp = moment(date).format('M/DD');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
timestamp = moment(date).format('M/DD/YYYY');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!item) {
|
|
||||||
updateState({ contacts, logo, subject, topic });
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.cardId) {
|
|
||||||
contacts.push(card.state.cards.get(item.cardId));
|
|
||||||
}
|
|
||||||
if (item?.detail?.members) {
|
|
||||||
const profileGuid = profile.state.identity.guid;
|
|
||||||
item.detail.members.forEach(guid => {
|
|
||||||
if (profileGuid !== guid) {
|
|
||||||
const contact = getCard(guid);
|
|
||||||
contacts.push(contact);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contacts.length === 0) {
|
if (!loaded.current) {
|
||||||
logo = 'solution';
|
const cardValue = cardId ? card.state.cards.get(cardId) : null;
|
||||||
|
const channelValue = cardId ? cardValue?.get(channelId) : channel.state.channels.get(channelId);
|
||||||
|
if (channelValue) {
|
||||||
|
const { topicRevision, syncRevision, topicMarker } = channelValue;
|
||||||
|
curRevision = topicRevision;
|
||||||
|
setRevision = syncRevision;
|
||||||
|
marker = topicMarker;
|
||||||
|
const topicItems = await getTopicItems(cardId, channelId);
|
||||||
|
for (let topic: topicItems) {
|
||||||
|
topics.current.set(topic.topicId, topic);
|
||||||
}
|
}
|
||||||
else if (contacts.length === 1) {
|
updateState({ card: cardValue, channel: channelValue, topics: topics.current });
|
||||||
if (contacts[0]?.profile?.imageSet) {
|
loaded.current = true;
|
||||||
logo = card.actions.getCardLogo(contacts[0].cardId, contacts[0].profileRevision);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logo = 'avatar';
|
console.log("failed to load conversation");
|
||||||
|
syncing.current = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
logo = 'appstore';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item?.detail?.dataType === 'sealed') {
|
|
||||||
locked = true;
|
|
||||||
unlocked = item.unsealedDetail != null;
|
|
||||||
if (item.unsealedDetail?.subject) {
|
|
||||||
topic = item.unsealedDetail.subject;
|
|
||||||
subject = topic;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
seals = JSON.parse(item.detail.data).seals;
|
if (!marker) {
|
||||||
|
const delta = await getTopicDelta(cardId, channelId, null, COUNT, null, null);
|
||||||
|
await setTopicDelta(cardId, channelId, delta.topics);
|
||||||
|
setMarkerAndSync(cardId, channelId, topicMarker, topicRevision);
|
||||||
}
|
}
|
||||||
catch (err) {
|
if (loadMore && marker) {
|
||||||
console.log(err);
|
const delta = await getTopicDelta(cardId, channelId, null, COUNT, null, marker);
|
||||||
|
await setTopicDelta(cardId, channelId, delta.topics);
|
||||||
|
setTopicMarker(cardId, channelId, delta.topicMarker);
|
||||||
}
|
}
|
||||||
}
|
if (ignoreRevision || curTopicRevision.current !== setTopicRevision.current) {
|
||||||
else {
|
const delta = await getTopicDelta(cardId, channelId, setRevision, null, marker, null);
|
||||||
if (item?.detail?.data) {
|
await setTopicDelta(cardId, channelId, delta.topics);
|
||||||
try {
|
setSyncRevision(cardid, channelId, delta.topicRevision);
|
||||||
topic = JSON.parse(item?.detail?.data).subject;
|
|
||||||
subject = topic;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!subject) {
|
|
||||||
if (contacts.length) {
|
|
||||||
let names = [];
|
|
||||||
for (let contact of contacts) {
|
|
||||||
if (contact?.profile?.name) {
|
|
||||||
names.push(contact.profile.name);
|
|
||||||
}
|
|
||||||
else if (contact?.profile?.handle) {
|
|
||||||
names.push(contact?.profile?.handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subject = names.join(', ');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
subject = "Notes";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const pushEnabled = await getNotifications(item.cardId, item.channelId);
|
|
||||||
|
|
||||||
const { enableImage, enableAudio, enableVideo } = item.detail;
|
|
||||||
updateState({ topic, subject, logo, contacts, host: item.cardId, created: timestamp,
|
|
||||||
enableImage, enableAudio, enableVideo, pushEnabled, locked, unlocked, seals });
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
sync();
|
|
||||||
}, [card, channel]);
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
setChannel: (selected) => {
|
|
||||||
if (selected == null) {
|
|
||||||
setView.current++;
|
|
||||||
conversationId.current = null;
|
|
||||||
reset.current = true;
|
|
||||||
updateState({ subject: null, logo: null, locked: true, unlocked: false, contacts: [], topics: new Map() });
|
|
||||||
}
|
|
||||||
else if (selected.cardId !== conversationId.current?.cardId || selected.channelId !== conversationId.current?.channelId) {
|
|
||||||
setView.current++;
|
|
||||||
conversationId.current = selected;
|
|
||||||
reset.current = true;
|
|
||||||
updateState({ subject: null, logo: null, contacts: [], topics: new Map(), init: false,
|
|
||||||
cardId: selected.cardId, channelId: selected.channelId });
|
|
||||||
sync();
|
|
||||||
const { cardId, channelId, revision } = selected;
|
|
||||||
if (cardId) {
|
|
||||||
card.actions.setChannelReadRevision(cardId, channelId, revision);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
channel.actions.setReadRevision(channelId, revision);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getTopicAssetUrl: (topicId, assetId) => {
|
|
||||||
if (conversationId.current) {
|
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
|
||||||
return card.actions.getChannelTopicAssetUrl(cardId, channelId, topicId, assetId);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return channel.actions.getTopicAssetUrl(channelId, topicId, assetId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
addTopic: async (message, files) => {
|
|
||||||
if (conversationId.current) {
|
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
|
||||||
await card.actions.addChannelTopic(cardId, channelId, message, files);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
await channel.actions.addTopic(channelId, message, files);
|
|
||||||
}
|
|
||||||
force.current = true;
|
|
||||||
sync();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addSealedTopic: async (message, sealKey) => {
|
|
||||||
if (conversationId.current) {
|
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
|
||||||
await card.actions.addSealedChannelTopic(cardId, channelId, message, sealKey);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
await channel.actions.addSealedTopic(channelId, message, sealKey);
|
|
||||||
}
|
|
||||||
force.current = true;
|
|
||||||
sync();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
unsealTopic: async (topicId, sealKey) => {
|
|
||||||
try {
|
|
||||||
const topic = topics.current.get(topicId);
|
|
||||||
const { messageEncrypted, messageIv } = JSON.parse(topic.detail.data);
|
|
||||||
const iv = CryptoJS.enc.Hex.parse(messageIv);
|
|
||||||
const key = CryptoJS.enc.Hex.parse(sealKey);
|
|
||||||
const enc = CryptoJS.enc.Base64.parse(messageEncrypted);
|
|
||||||
let cipher = CryptoJS.lib.CipherParams.create({ ciphertext: enc, iv: iv });
|
|
||||||
const dec = CryptoJS.AES.decrypt(cipher, key, { iv: iv });
|
|
||||||
topic.unsealedDetail = JSON.parse(dec.toString(CryptoJS.enc.Utf8));
|
|
||||||
topics.current.set(topicId, { ...topic });
|
|
||||||
updateState({ topics: topics.current });
|
|
||||||
|
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
|
||||||
await card.actions.setChannelTopicUnsealedDetail(cardId, channelId, topic.topicId, topic.detailRevision, topic.unsealedDetail);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
await channel.actions.setTopicUnsealedDetail(channelId, topic.topicId, topic.detailRevision, topic.unsealedDetail);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(err) {
|
catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
updateState({ offysnc: true });
|
||||||
|
syncing.current = false;
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
syncing.current = false;
|
||||||
|
await sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const setTopicDelta(cardId, channelId, entries) => {
|
||||||
|
for (let entry of entries) {
|
||||||
|
if (entry.data) {
|
||||||
|
if (entry.data.detail) {
|
||||||
|
const item = mapTopicEntry(entry);
|
||||||
|
topics.current.set(item.topicId, item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const topic = await getTopic(cardId, channelId, entry.id);
|
||||||
|
const item = mapTopicEntry(entry);
|
||||||
|
topics.current.set(item.topicId, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clearTopicItem(entry.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateState({ offsync: false, topics: topics.current });
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
update.current = true;
|
||||||
|
sync();
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [card.state, channel.state]);
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
setConversation: async (cardId, channelId) => {
|
||||||
|
conversationId.current = { cardId, channelId };
|
||||||
|
reset.current = true;
|
||||||
|
await sync();
|
||||||
},
|
},
|
||||||
setSubject: async (subject) => {
|
clearConversation: async ()
|
||||||
if (conversationId.current) {
|
conversationId.current = null;
|
||||||
const { cardId, channelId } = conversationId.current;
|
reset.current = true;
|
||||||
|
await sync();
|
||||||
|
},
|
||||||
|
setChannelSubject: async (type, subject) => {
|
||||||
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
if (cardId) {
|
if (cardId) {
|
||||||
throw new Error("can only set hosted channel subjects");
|
throw new Error("can only set hosted channel subjects");
|
||||||
}
|
}
|
||||||
await channel.actions.setSubject(channelId, subject);
|
else if(channelId) {
|
||||||
|
await channel.actions.setSubject(channelId, type, subject);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setSealedSubject: async (subject, sealKey) => {
|
removeChannel: async () => {
|
||||||
if (conversationId.current) {
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
if (cardId) {
|
||||||
throw new Error("can only set hosted channel subjects");
|
await card.actions.removeChannel(cardId, channelId);
|
||||||
}
|
}
|
||||||
await channel.actions.setSealedSubject(channelId, subject, sealKey);
|
else if (channelId) {
|
||||||
|
await channel.actions.removeChannel(channelId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
remove: async () => {
|
getNotifications: async () => {
|
||||||
if (conversationId.current) {
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
const { cardId, channelId } = conversationId.current;
|
if (cardId) {
|
||||||
await remove(cardId, channelId);
|
await card.actions.getChannelNotifications(cardId, channelId);
|
||||||
|
}
|
||||||
|
else if (channelId) {
|
||||||
|
await channel.actions.getNotifications(channelId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setNotifications: async (notify) => {
|
setNotifications: async (notify) => {
|
||||||
if (conversationId.current) {
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
const { cardId, channelId } = conversationId.current;
|
if (cardId) {
|
||||||
await setNotifications(cardId, channelId, notify);
|
await card.actions.setChannelNotifications(cardId, channelId);
|
||||||
updateState({ pushEnabled: notify });
|
}
|
||||||
|
else if (channelId) {
|
||||||
|
await channel.actions.setNotifications(channelId, notify);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeTopic: async (topicId) => {
|
setChannelCard: async (id) => {
|
||||||
if (conversationId.current) {
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
if (cardId) {
|
||||||
await card.actions.removeChannelTopic(cardId, channelId, topicId);
|
throw new Error("can only set members on hosted channel");
|
||||||
|
}
|
||||||
|
else if (channelId) {
|
||||||
|
await channel.actions.setChannelCard(channelId, id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearChannelCard: async (id) => {
|
||||||
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
|
if (cardId) {
|
||||||
|
throw new Error("can only clear members on hosted channel");
|
||||||
|
}
|
||||||
|
else if (channelId) {
|
||||||
|
await channel.actions.clearChannelCard(channelId, id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addChannelAlert: async () => {
|
||||||
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
|
if (cardId) {
|
||||||
|
return await card.actions.addChannelAlert(cardId, channelId);
|
||||||
|
}
|
||||||
|
else if (channelId) {
|
||||||
|
return await channel.actions.addChannelAlert(channelId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setChannelFlag: async () => {
|
||||||
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
|
if (cardId) {
|
||||||
|
await card.actions.setChannelFlag(cardId, channelId);
|
||||||
|
}
|
||||||
|
else if (channelId) {
|
||||||
|
await channel.actions.setChannelFlag(channelId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearChannelFlag: async () => {
|
||||||
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
|
if (cardid) {
|
||||||
|
await card.actions.clearChannelFlag(cardId, channelId);
|
||||||
|
}
|
||||||
|
else if (channelId) {
|
||||||
|
await channel.actions.clearChannelFlag(channelId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addTopic: async (type, message, files) => {
|
||||||
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
|
if (cardId) {
|
||||||
|
await card.actions.addTopic(cardId, channelId, type, message, files);
|
||||||
|
}
|
||||||
|
else if (channelId) {
|
||||||
|
await channel.actions.addTopic(channelId, type, message, files);
|
||||||
|
}
|
||||||
|
force.current = true;
|
||||||
|
await sync();
|
||||||
|
},
|
||||||
|
removeTopic: async (topicId) => {
|
||||||
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
|
if (cardId) {
|
||||||
|
await card.actions.removeTopic(cardId, channelId, topicId);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await channel.actions.removeTopic(channelId, topicId);
|
await channel.actions.removeTopic(channelId, topicId);
|
||||||
}
|
}
|
||||||
force.current = true;
|
force.current = true;
|
||||||
sync();
|
await sync();
|
||||||
}
|
|
||||||
},
|
},
|
||||||
setTopicSubject: async (topicId, data) => {
|
unsealTopic: async (topicId, revision, unsealed) => {
|
||||||
if (conversationId.current) {
|
const { cardId, channelId } = conversationId.current || {}
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
if (cardId) {
|
||||||
return await card.actions.setChannelTopicSubject(cardId, channelId, topicId, 'superbasictopic', data);
|
await card.actions.setUnsealedTopicSubject(cardId, channelId, topicId, revision, unsealed);
|
||||||
}
|
}
|
||||||
else {
|
else {channelId) {
|
||||||
return await channel.actions.setTopicSubject(channelId, topicId, 'superbasictopic', data);
|
await channel.actions.setUnsealedTopicSubject(channelId, topicId, revision, unsealed);
|
||||||
}
|
}
|
||||||
|
setTopicField(topicId, 'unsaledDetail', unsealed);
|
||||||
|
},
|
||||||
|
setTopicSubject: async (topicId, type, subject) => {
|
||||||
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
|
if (cardId) {
|
||||||
|
await card.actions.setTopicSubject(cardId, channelId, topicId, type, subject);
|
||||||
|
}
|
||||||
|
else if (channelId) {
|
||||||
|
await channel.actions.setTopicSubject(channelId, topicId, type, subject);
|
||||||
}
|
}
|
||||||
force.current = true;
|
force.current = true;
|
||||||
sync();
|
await sync();
|
||||||
},
|
},
|
||||||
setSealedTopicSubject: async (topicId, data, sealKey) => {
|
addTopicAlert: async (topicId) => {
|
||||||
if (conversationId.current) {
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
|
|
||||||
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
|
||||||
const key = CryptoJS.enc.Hex.parse(sealKey);
|
|
||||||
const encrypted = CryptoJS.AES.encrypt(JSON.stringify({ message: data }), key, { iv: iv });
|
|
||||||
const messageEncrypted = encrypted.ciphertext.toString(CryptoJS.enc.Base64)
|
|
||||||
const messageIv = iv.toString();
|
|
||||||
|
|
||||||
if (cardId) {
|
if (cardId) {
|
||||||
return await card.actions.setChannelTopicSubject(cardId, channelId, topicId, 'sealedtopic', { messageEncrypted, messageIv });
|
return await card.actions.addTopicAlert(cardId, channelId, topicId);
|
||||||
}
|
}
|
||||||
else {
|
else if (channelId) {
|
||||||
return await channel.actions.setTopicSubject(channelId, topicId, 'sealedtopic', { messageEncrypted, messageIv });
|
return await channel.actions.addTopicAlert(channelId, topicId);
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setCard: async (id) => {
|
setTopicFlag: async (topicId) => {
|
||||||
if (conversationId.current) {
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
if (cardId) {
|
||||||
throw new Error("can only set members on hosted channel");
|
card.actions.setTopicFlag(cardId, channelId, topicId);
|
||||||
}
|
}
|
||||||
await channel.actions.setCard(channelId, id);
|
else if (channelId) {
|
||||||
|
channel.actions.setTopicFlag(channelId, topicId);
|
||||||
}
|
}
|
||||||
|
setTopicField(topicId, 'blocked', true);
|
||||||
},
|
},
|
||||||
clearCard: async (id) => {
|
clearTopicFlag: async (topicId) => {
|
||||||
if (conversationId.current) {
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
if (cardId) {
|
||||||
throw new Error("can only clear members on hosted channel");
|
card.actions.clearTopicFlag(cardId, channelId, topicId);
|
||||||
}
|
}
|
||||||
await channel.actions.clearCard(channelId, id);
|
else if (channelId) {
|
||||||
|
channel.actions.clearTopicFlag(channelId, topicId);
|
||||||
}
|
}
|
||||||
|
setTopicField(topicId, 'blocked', false);
|
||||||
},
|
},
|
||||||
addReport: async () => {
|
getTopicAssetUrl: (topicId, assetId) => {
|
||||||
if (conversationId.current) {
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
const { cardId, channelId } = conversationId.current;
|
return getTopicAssetUrl(cardId, channelId, topicId, assetId);
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.addChannelReport(cardId, channelId);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return await channel.actions.addReport(channelId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addTopicReport: async(topicId) => {
|
|
||||||
if (conversationId.current) {
|
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
|
||||||
return await card.actions.addChannelTopicReport(cardId, channelId, topicId);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return await channel.actions.addTopicReport(channelId, topicId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setBlocked: async () => {
|
|
||||||
if (conversationId.current) {
|
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
|
||||||
await card.actions.setChannelBlocked(cardId, channelId);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
await channel.actions.setBlocked(channelId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
blockTopic: async (topicId) => {
|
|
||||||
if (conversationId.current) {
|
|
||||||
const { cardId, channelId } = conversationId.current;
|
|
||||||
if (cardId) {
|
|
||||||
await card.actions.setChannelTopicBlocked(cardId, channelId, topicId);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
await channel.actions.setTopicBlocked(channelId, topicId);
|
|
||||||
}
|
|
||||||
const topic = topics.current.get(topicId);
|
|
||||||
if (topic) {
|
|
||||||
topic.blocked = 1;
|
|
||||||
force.current = true;
|
|
||||||
sync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
unblockTopic: async (cardId, channelId, topicId) => {
|
|
||||||
if (conversationId.current) {
|
|
||||||
if (conversationId.current.cardId == cardId && conversationId.current.channelId == channelId) {
|
|
||||||
const topic = topics.current.get(topicId);
|
|
||||||
if (topic) {
|
|
||||||
topic.blocked = 0;
|
|
||||||
force.current = true;
|
|
||||||
sync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
loadMore: () => {
|
loadMore: () => {
|
||||||
if (conversationId.current) {
|
|
||||||
more.current = true;
|
more.current = true;
|
||||||
sync();
|
sync();
|
||||||
}
|
|
||||||
},
|
},
|
||||||
resync: () => {
|
resync: () => {
|
||||||
if (conversationId.current) {
|
|
||||||
force.current = true;
|
force.current = true;
|
||||||
sync();
|
sync();
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getTopicItems = async (cardId, channelId) => {
|
||||||
|
if (cardId) {
|
||||||
|
return await card.actions.getTopicItems(cardId, channelId);
|
||||||
|
}
|
||||||
|
return await channel.actions.getTopicItems(channelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setTopicItem = async (cardId, channelId, topic) => {
|
||||||
|
if (cardId) {
|
||||||
|
return await card.actions.setTopicItem(cardId, channelId, topic);
|
||||||
|
}
|
||||||
|
return await channel.actions.setTopicItem(channelId, topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearTopicItem = async (cardId, channelId, topicId) => {
|
||||||
|
if (cardId) {
|
||||||
|
return await card.actions.clearTopicItem(cardId, channelId, topicId);
|
||||||
|
}
|
||||||
|
return await channel.actions.clearTopicItem(channelId, topicId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setTopicMarker = async (cardId, channelId, marker) => {
|
||||||
|
if (cardId) {
|
||||||
|
return await card.actions.setChannelTopicMarker(cardId, channelId, marker);
|
||||||
|
}
|
||||||
|
return await channel.actions.setTopicMarker(channelId, marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setSyncRevision = async (cardId, channelId, revision) => {
|
||||||
|
if (cardId) {
|
||||||
|
return await card.actions.setChannelSyncRevision(cardId, channelId, revision);
|
||||||
|
}
|
||||||
|
return await channel.actions.setSyncRevision(channelid, revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setMarkerAndSync = async (cardId, channelId, marker, revision) => {
|
||||||
|
if (cardId) {
|
||||||
|
return await card.actions.setChannelMarkerAndSync(cardId, channelId, marker, revision);
|
||||||
|
}
|
||||||
|
return await channel.actions.setMarkerAndSync(channelId, marker, revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTopicDelta = async (cardId, channelId, revision, count, begin, end) => {
|
||||||
|
if (cardId) {
|
||||||
|
return await card.actions.getTopics(cardId, channelId, revision, count, begin, end);
|
||||||
|
}
|
||||||
|
return await channel.actions.getTopics(channelId, revision, count, begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTopic = async (cardId, channelId, topicId) => {
|
||||||
|
if (cardId) {
|
||||||
|
return await card.actions.getTopic(cardId, channelId, topicId);
|
||||||
|
}
|
||||||
|
return await channel.actions.getTopic(channelId, topicId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapTopicItem = (entry) => {
|
||||||
|
return {
|
||||||
|
topicId: entry.id,
|
||||||
|
revision: entry.revision,
|
||||||
|
detailRevision = entry.data?.detailRevision,
|
||||||
|
detail = entry.data?.topicDetail,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const setTopicField = (topicId, field, value) => {
|
||||||
|
const topic = topics.current.get(topicId);
|
||||||
|
if (topic) {
|
||||||
|
topic[field] = value;
|
||||||
|
}
|
||||||
|
topics.current.set(topicId, topic);
|
||||||
|
updateState({ topics: topics.current });
|
||||||
|
};
|
||||||
|
|
||||||
return { state, actions }
|
return { state, actions }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,17 +159,6 @@ export function useStoreContext() {
|
|||||||
blocked: values[0].blocked,
|
blocked: values[0].blocked,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getCardItemView: async (guid, cardId) => {
|
|
||||||
const values = await getAppValues(db.current, `SELECT revision, detail_revision, profile_revision FROM card_${guid} WHERE card_id=?`, [cardId]);
|
|
||||||
if (!values.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
revision: values[0].revision,
|
|
||||||
detailRevision: values[0].detail_revision,
|
|
||||||
profileRevision: values[0].profile_revision,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
getCardItems: async (guid) => {
|
getCardItems: async (guid) => {
|
||||||
const values = await getAppValues(db.current, `SELECT card_id, revision, detail_revision, profile_revision, detail, profile, offsync, blocked, notified_view, notified_profile, notified_article, notified_channel FROM card_${guid}`, []);
|
const values = await getAppValues(db.current, `SELECT card_id, revision, detail_revision, profile_revision, detail, profile, offsync, blocked, notified_view, notified_profile, notified_article, notified_channel FROM card_${guid}`, []);
|
||||||
return values.map(card => ({
|
return values.map(card => ({
|
||||||
@ -215,6 +204,9 @@ export function useStoreContext() {
|
|||||||
setChannelItemTopicMarker: async (guid, channelId, marker) => {
|
setChannelItemTopicMarker: async (guid, channelId, marker) => {
|
||||||
await db.current.executeSql(`UPDATE channel_${guid} set topic_marker=? where channel_id=?`, [marker, channelId]);
|
await db.current.executeSql(`UPDATE channel_${guid} set topic_marker=? where channel_id=?`, [marker, channelId]);
|
||||||
},
|
},
|
||||||
|
setChannelItemMarkerAndSync: async (guid, channelId, marker, revision) => {
|
||||||
|
await db.current.executeSql(`UPDATE channel_${guid} set sync_revision=?, topic_marker=? where channel_id=?`, [revision, maker, channelId]);
|
||||||
|
},
|
||||||
setChannelItemBlocked: async (guid, channelId) => {
|
setChannelItemBlocked: async (guid, channelId) => {
|
||||||
await db.current.executeSql(`UPDATE channel_${guid} set blocked=? where channel_id=?`, [1, channelId]);
|
await db.current.executeSql(`UPDATE channel_${guid} set blocked=? where channel_id=?`, [1, channelId]);
|
||||||
},
|
},
|
||||||
@ -233,17 +225,6 @@ export function useStoreContext() {
|
|||||||
setChannelItemUnsealedSummary: async (guid, channelId, revision, unsealed) => {
|
setChannelItemUnsealedSummary: async (guid, channelId, revision, unsealed) => {
|
||||||
await db.current.executeSql(`UPDATE channel_${guid} set unsealed_summary=? where topic_revision=? AND channel_id=?`, [encodeObject(unsealed), revision, channelId]);
|
await db.current.executeSql(`UPDATE channel_${guid} set unsealed_summary=? where topic_revision=? AND channel_id=?`, [encodeObject(unsealed), revision, channelId]);
|
||||||
},
|
},
|
||||||
getChannelItemView: async (guid, channelId) => {
|
|
||||||
const values = await getAppValues(db.current, `SELECT revision, detail_revision, topic_revision FROM channel_${guid} WHERE channel_id=?`, [channelId]);
|
|
||||||
if (!values.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
revision: values[0].revision,
|
|
||||||
detailRevision: values[0].detail_revision,
|
|
||||||
topicRevision: values[0].topic_revision,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
getChannelItems: async (guid) => {
|
getChannelItems: async (guid) => {
|
||||||
const values = await getAppValues(db.current, `SELECT channel_id, read_revision, revision, sync_revision, blocked, detail_revision, topic_revision, topic_marker, detail, unsealed_detail, summary, unsealed_summary FROM channel_${guid}`, []);
|
const values = await getAppValues(db.current, `SELECT channel_id, read_revision, revision, sync_revision, blocked, detail_revision, topic_revision, topic_marker, detail, unsealed_detail, summary, unsealed_summary FROM channel_${guid}`, []);
|
||||||
return values.map(channel => ({
|
return values.map(channel => ({
|
||||||
@ -318,6 +299,9 @@ export function useStoreContext() {
|
|||||||
setCardChannelItemTopicMarker: async (guid, cardId, channelId, marker) => {
|
setCardChannelItemTopicMarker: async (guid, cardId, channelId, marker) => {
|
||||||
await db.current.executeSql(`UPDATE card_channel_${guid} set topic_marker=? where card_id=? and channel_id=?`, [marker, cardId, channelId]);
|
await db.current.executeSql(`UPDATE card_channel_${guid} set topic_marker=? where card_id=? and channel_id=?`, [marker, cardId, channelId]);
|
||||||
},
|
},
|
||||||
|
setCardChannelItemMakerAndSync: async (guid, cardId, channelId, marker, revision) => {
|
||||||
|
await db.current.executeSql(`UPDATE card_channel_${guid} set topic_marker=?, sync_revision=? where card_id=? and channel_id=?`, [marker, revision, cardId, channelId]);
|
||||||
|
},
|
||||||
setCardChannelItemDetail: async (guid, cardId, channelId, revision, detail) => {
|
setCardChannelItemDetail: async (guid, cardId, channelId, revision, detail) => {
|
||||||
await db.current.executeSql(`UPDATE card_channel_${guid} set detail_revision=?, detail=?, unsealed_detail=null where card_id=? and channel_id=?`, [revision, encodeObject(detail), cardId, channelId]);
|
await db.current.executeSql(`UPDATE card_channel_${guid} set detail_revision=?, detail=?, unsealed_detail=null where card_id=? and channel_id=?`, [revision, encodeObject(detail), cardId, channelId]);
|
||||||
},
|
},
|
||||||
@ -330,17 +314,6 @@ export function useStoreContext() {
|
|||||||
setCardChannelItemUnsealedSummary: async (guid, cardId, channelId, revision, unsealed) => {
|
setCardChannelItemUnsealedSummary: async (guid, cardId, channelId, revision, unsealed) => {
|
||||||
await db.current.executeSql(`UPDATE card_channel_${guid} set unsealed_summary=? where topic_revision=? AND card_id=? AND channel_id=?`, [encodeObject(unsealed), revision, cardId, channelId]);
|
await db.current.executeSql(`UPDATE card_channel_${guid} set unsealed_summary=? where topic_revision=? AND card_id=? AND channel_id=?`, [encodeObject(unsealed), revision, cardId, channelId]);
|
||||||
},
|
},
|
||||||
getCardChannelItemView: async (guid, cardId, channelId) => {
|
|
||||||
const values = await getAppValues(db.current, `SELECT revision, detail_revision, topic_revision FROM card_channel_${guid} WHERE card_id=? and channel_id=?`, [cardId, channelId]);
|
|
||||||
if (!values.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
revision: values[0].revision,
|
|
||||||
detailRevision: values[0].detail_revision,
|
|
||||||
topicRevision: values[0].topic_revision,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
getCardChannelItems: async (guid) => {
|
getCardChannelItems: async (guid) => {
|
||||||
const values = await getAppValues(db.current, `SELECT card_id, channel_id, read_revision, sync_revision, revision, blocked, detail_revision, topic_revision, topic_marker, detail, unsealed_detail, summary, unsealed_summary FROM card_channel_${guid}`, []);
|
const values = await getAppValues(db.current, `SELECT card_id, channel_id, read_revision, sync_revision, revision, blocked, detail_revision, topic_revision, topic_marker, detail, unsealed_detail, summary, unsealed_summary FROM card_channel_${guid}`, []);
|
||||||
return values.map(channel => ({
|
return values.map(channel => ({
|
||||||
|
Loading…
Reference in New Issue
Block a user