implemented optimized thead loading based on message creation time

This commit is contained in:
Roland Osborne 2023-05-05 13:40:32 -07:00
parent 2e28584ae1
commit b57b32b55c
5 changed files with 142 additions and 15 deletions

View File

@ -67,8 +67,9 @@ export function useAppContext() {
}, []);
const setSession = async () => {
const { loginTimestamp } = access.current;
const { loginTimestamp, guid } = access.current;
updateState({ session: true, loginTimestamp, status: 'connecting' });
await store.actions.updateDb(guid);
await account.actions.setSession(access.current);
await profile.actions.setSession(access.current);
await card.actions.setSession(access.current);

View File

@ -493,6 +493,14 @@ export function useCardContext() {
const { guid } = access.current || {};
return await store.actions.getCardChannelTopicItems(guid, cardId, channelId);
},
getTopicItemsId: async (cardId, channelId) => {
const { guid } = access.current || {};
return await store.actions.getCardChannelTopicItemsId(guid, cardId, channelId);
},
getTopicItemsById: async (cardId, channelId, topics) => {
const { guid } = access.current || {};
return await store.actions.getCardChannelTopicItemsById(guid, cardId, channelId, topics);
},
setTopicItem: async (cardId, channelId, topicId, topic) => {
const { guid } = access.current || {};
return await store.actions.setCardChannelTopicItem(guid, cardId, channelId, topicId, topic);

View File

@ -263,6 +263,14 @@ export function useChannelContext() {
const { guid } = access.current || {};
return await store.actions.getChannelTopicItems(guid, channelId);
},
getTopicItemsId: async (channelId) => {
const { guid } = access.current || {};
return await store.actions.getChannelTopicItemsId(guid, channelId);
},
getTopicItemsById: async (channelId, topics) => {
const { guid } = access.current || {};
return await store.actions.getChannelTopicItemsById(guid, channelId, topics);
},
setTopicItem: async (channelId, topic) => {
const { guid } = access.current || {};
return await store.actions.setChannelTopicItem(guid, channelId, topic);

View File

@ -7,7 +7,7 @@ import { ProfileContext } from 'context/ProfileContext';
import CryptoJS from 'crypto-js';
export function useConversationContext() {
const COUNT = 48;
const COUNT = 32;
const [state, setState] = useState({
loaded: false,
@ -25,6 +25,7 @@ export function useConversationContext() {
const syncing = useRef(false);
const update = useRef(false);
const loaded = useRef(false);
const stored = useRef([]);
const conversationId = useRef(null);
const topics = useRef(new Map());
@ -63,7 +64,26 @@ export function useConversationContext() {
if (channelValue) {
if (!loaded.current) {
const topicItems = await getTopicItems(cardId, channelId);
stored.current = await getTopicItemsId(cardId, channelId);
stored.current.sort((a,b) => {
if (a.created > b.created) {
return -1;
}
if (a.created < b.created) {
return 1;
}
return 0;
});
const ids = [];
for (let i = 0; i < COUNT; i++) {
if (stored.current.length > 0) {
ids.push(stored.current.shift().topicId);
}
}
const topicItems = await getTopicItemsById(cardId, channelId, ids);
for (let topic of topicItems) {
topics.current.set(topic.topicId, topic);
}
@ -94,12 +114,27 @@ export function useConversationContext() {
updateState({ loaded: true, offsync: false, topics: topics.current, card: cardValue, channel: channelValue });
}
else if (loadMore) {
const delta = await getTopicDelta(cardId, channelId, null, COUNT, null, curTopicMarker.current);
const marker = delta.marker ? delta.marker : 1;
await setTopicDelta(cardId, channelId, delta.topics);
await setTopicMarker(cardId, channelId, marker);
curTopicMarker.current = marker;
updateState({ loaded: true, offsync: false, topics: topics.current, card: cardValue, channel: channelValue });
if (stored.current.length > 0) {
const ids = [];
for (let i = 0; i < COUNT; i++) {
if (stored.current.length > 0) {
ids.push(stored.current.shift().topicId);
}
}
const topicItems = await getTopicItemsById(cardId, channelId, ids);
for (let topic of topicItems) {
topics.current.set(topic.topicId, topic);
}
updateState({ loaded: true, topics: topics.current, card: cardValue, channel: channelValue });
}
else {
const delta = await getTopicDelta(cardId, channelId, null, COUNT, null, curTopicMarker.current);
const marker = delta.marker ? delta.marker : 1;
await setTopicDelta(cardId, channelId, delta.topics);
await setTopicMarker(cardId, channelId, marker);
curTopicMarker.current = marker;
updateState({ loaded: true, offsync: false, topics: topics.current, card: cardValue, channel: channelValue });
}
}
else if (ignoreRevision || topicRevision > curSyncRevision.current) {
const delta = await getTopicDelta(cardId, channelId, curSyncRevision.current, null, curTopicMarker.current, null);
@ -347,6 +382,20 @@ export function useConversationContext() {
},
}
const getTopicItemsId = async (cardId, channelId) => {
if (cardId) {
return await card.actions.getTopicItemsId(cardId, channelId);
}
return await channel.actions.getTopicItemsId(channelId);
}
const getTopicItemsById = async (cardId, channelId, topics) => {
if (cardId) {
return await card.actions.getTopicItemsById(cardId, channelId, topics);
}
return await channel.actions.getTopicItemsById(channelId, topics);
}
const getTopicItems = async (cardId, channelId) => {
if (cardId) {
return await card.actions.getTopicItems(cardId, channelId);

View File

@ -13,10 +13,23 @@ export function useStoreContext() {
const initSession = async (guid) => {
await db.current.executeSql(`CREATE TABLE IF NOT EXISTS channel_${guid} (channel_id text, revision integer, detail_revision integer, topic_revision integer, topic_marker integer, blocked integer, sync_revision integer, detail text, unsealed_detail text, summary text, unsealed_summary text, offsync integer, read_revision integer, unique(channel_id))`);
await db.current.executeSql(`CREATE TABLE IF NOT EXISTS channel_topic_${guid} (channel_id text, topic_id text, revision integer, detail_revision integer, blocked integer, detail text, unsealed_detail text, unique(channel_id, topic_id))`);
await db.current.executeSql(`CREATE TABLE IF NOT EXISTS channel_topic_${guid} (channel_id text, topic_id text, revision integer, created integer, detail_revision integer, blocked integer, detail text, unsealed_detail text, unique(channel_id, topic_id))`);
await db.current.executeSql(`CREATE TABLE IF NOT EXISTS card_${guid} (card_id text, revision integer, detail_revision integer, profile_revision integer, detail text, profile text, notified_view integer, notified_article integer, notified_profile integer, notified_channel integer, offsync integer, blocked integer, unique(card_id))`);
await db.current.executeSql(`CREATE TABLE IF NOT EXISTS card_channel_${guid} (card_id text, channel_id text, revision integer, detail_revision integer, topic_revision integer, topic_marker integer, sync_revision integer, detail text, unsealed_detail text, summary text, unsealed_summary text, offsync integer, blocked integer, read_revision integer, unique(card_id, channel_id))`);
await db.current.executeSql(`CREATE TABLE IF NOT EXISTS card_channel_topic_${guid} (card_id text, channel_id text, topic_id text, revision integer, detail_revision integer, blocked integer, detail text, unsealed_detail text, unique(card_id, channel_id, topic_id))`);
await db.current.executeSql(`CREATE TABLE IF NOT EXISTS card_channel_topic_${guid} (card_id text, channel_id text, topic_id text, revision integer, created integer, detail_revision integer, blocked integer, detail text, unsealed_detail text, unique(card_id, channel_id, topic_id))`);
}
const hasColumn = async (table, column) => {
const pragma = await db.current.executeSql(`PRAGMA table_info(${table})`);
if (pragma?.length === 1) {
for (let i = 0; i < pragma[0].rows.length; i++) {
const col = pragma[0].rows.item(i);
if (col.name === column) {
return true;
}
}
}
return false
}
const actions = {
@ -28,6 +41,16 @@ export function useStoreContext() {
await db.current.executeSql("INSERT OR IGNORE INTO app (key, value) values ('session', null);");
return await getAppValue(db.current, 'session');
},
updateDb: async (guid) => {
const hasChannel = await hasColumn(`channel_topic_${guid}`, 'created');
if (!hasChannel) {
await db.current.executeSql(`ALTER TABLE channel_topic_${guid} ADD COLUMN created integer default 0`);
}
const hasCardChannel = await hasColumn(`card_channel_topic_${guid}`, 'created');
if (!hasCardChannel) {
await db.current.executeSql(`ALTER TABLE card_channel_topic_${guid} ADD COLUMN created integer default 0`);
}
},
setSession: async (access) => {
await initSession(access.guid);
await db.current.executeSql("UPDATE app SET value=? WHERE key='session';", [encodeObject(access)]);
@ -240,9 +263,28 @@ export function useStoreContext() {
unsealedDetail: decodeObject(topic.unsealed_detail),
}));
},
getChannelTopicItemsId: async (guid, channelId) => {
const values = await getAppValues(db.current, `SELECT topic_id, created FROM channel_topic_${guid} WHERE channel_id=?`, [channelId]);
return values.map(topic => ({
topicId: topic.topic_id,
created: topic.created,
}));
},
getChannelTopicItemsById: async (guid, channelId, topics) => {
const q = topics.map(() => '?');
const values = await getAppValues(db.current, `SELECT topic_id, revision, blocked, detail_revision, detail, unsealed_detail FROM channel_topic_${guid} WHERE channel_id=? AND topic_id in (${q.join(',')})`, [channelId, ...topics]);
return values.map(topic => ({
topicId: topic.topic_id,
revision: topic.revision,
blocked: topic.blocked,
detailRevision: topic.detail_revision,
detail: decodeObject(topic.detail),
unsealedDetail: decodeObject(topic.unsealed_detail),
}));
},
setChannelTopicItem: async (guid, channelId, topic) => {
const { topicId, revision, detailRevision, detail } = topic;
await db.current.executeSql(`INSERT OR REPLACE INTO channel_topic_${guid} (channel_id, topic_id, revision, detail_revision, blocked, detail, unsealed_detail) values (?, ?, ?, ?, false, ?, null);`, [channelId, topicId, revision, detailRevision, encodeObject(detail)]);
await db.current.executeSql(`INSERT OR REPLACE INTO channel_topic_${guid} (channel_id, topic_id, revision, created, detail_revision, blocked, detail, unsealed_detail) values (?, ?, ?, ?, ?, false, ?, null);`, [channelId, topicId, revision, detail?.created, detailRevision, encodeObject(detail)]);
},
setChannelTopicItemUnsealedDetail: async (guid, channelId, topicId, revision, unsealed) => {
await db.current.executeSql(`UPDATE channel_topic_${guid} set unsealed_detail=? where detail_revision=? AND channel_id=? AND topic_id=?`, [encodeObject(unsealed), revision, channelId, topicId]);
@ -329,11 +371,30 @@ export function useStoreContext() {
detailRevision: topic.detail_revision,
detail: decodeObject(topic.detail),
unsealedDetail: decodeObject(topic.unsealed_detail),
}));
},
}));
},
getCardChannelTopicItemsId: async (guid, cardId, channelId) => {
const values = await getAppValues(db.current, `SELECT topic_id, created FROM card_channel_topic_${guid} WHERE card_id=? AND channel_id=?`, [cardId, channelId]);
return values.map(topic => ({
topicId: topic.topic_id,
created: topic.created,
}));
},
getCardChannelTopicItemsById: async (guid, cardId, channelId, topics) => {
const q = topics.map(() => '?');
const values = await getAppValues(db.current, `SELECT topic_id, revision, blocked, detail_revision, detail, unsealed_detail FROM card_channel_topic_${guid} WHERE card_id=? AND channel_id=? AND topic_id in (${q.join(',')})`, [cardId, channelId, ...topics]);
return values.map(topic => ({
topicId: topic.topic_id,
revision: topic.revision,
blocked: topic.blocked,
detailRevision: topic.detail_revision,
detail: decodeObject(topic.detail),
unsealedDetail: decodeObject(topic.unsealed_detail),
}));
},
setCardChannelTopicItem: async (guid, cardId, channelId, topic) => {
const { topicId, revision, detailRevision, detail } = topic;
await db.current.executeSql(`INSERT OR REPLACE INTO card_channel_topic_${guid} (card_id, channel_id, topic_id, revision, detail_revision, detail, unsealed_detail) values (?, ?, ?, ?, ?, ?, null);`, [cardId, channelId, topicId, revision, detailRevision, encodeObject(detail)]);
await db.current.executeSql(`INSERT OR REPLACE INTO card_channel_topic_${guid} (card_id, channel_id, topic_id, revision, created, detail_revision, detail, unsealed_detail) values (?, ?, ?, ?, ?, ?, ?, null);`, [cardId, channelId, topicId, revision, topic?.created, detailRevision, encodeObject(detail)]);
},
setCardChannelTopicItemUnsealedDetail: async (guid, cardId, channelId, topicId, revision, unsealed) => {
await db.current.executeSql(`UPDATE card_channel_topic_${guid} set unsealed_detail=? where detail_revision=? AND card_id=? AND channel_id=? AND topic_id=?`, [encodeObject(unsealed), revision, cardId, channelId, topicId]);