merged back support for sealed messages

This commit is contained in:
Roland Osborne 2023-03-02 14:48:53 -08:00
parent c8dec078aa
commit e4f55861d0
9 changed files with 61 additions and 44 deletions

View File

@ -2,9 +2,6 @@ import { checkResponse, fetchWithTimeout } from './fetchUtil';
export async function getContactChannelTopics(server, token, channelId, revision, count, begin, end) { export async function getContactChannelTopics(server, token, channelId, revision, count, begin, end) {
console.log("GETTING:", revision, count, begin, end);
let rev = '' let rev = ''
if (revision != null) { if (revision != null) {
rev = `&revision=${revision}` rev = `&revision=${revision}`
@ -25,8 +22,6 @@ console.log("GETTING:", revision, count, begin, end);
{ method: 'GET' }); { method: 'GET' });
checkResponse(topics) checkResponse(topics)
console.log(topics.headers);
return { return {
marker: topics.headers.get('topic-marker'), marker: topics.headers.get('topic-marker'),
revision: topics.headers.get('topic-revision'), revision: topics.headers.get('topic-revision'),

View File

@ -156,7 +156,6 @@ export function useAppContext() {
const setWebsocket = (session) => { const setWebsocket = (session) => {
ws.current = createWebsocket(`wss://${session.server}/status`); ws.current = createWebsocket(`wss://${session.server}/status`);
ws.current.onmessage = (ev) => { ws.current.onmessage = (ev) => {
console.log("ON MESSAGE!");
try { try {
delay.current = 0; delay.current = 0;
const rev = JSON.parse(ev.data); const rev = JSON.parse(ev.data);

View File

@ -14,7 +14,6 @@ export function useConversationContext() {
topics: new Map(), topics: new Map(),
card: null, card: null,
channel: null, channel: null,
notification: null,
}); });
const card = useContext(CardContext); const card = useContext(CardContext);
const channel = useContext(ChannelContext); const channel = useContext(ChannelContext);
@ -39,7 +38,6 @@ export function useConversationContext() {
if (!syncing.current && (reset.current || update.current || force.current || more.current)) { if (!syncing.current && (reset.current || update.current || force.current || more.current)) {
console.log("SYNCING!", reset.current, update.current, force.current, more.current);
const loadMore = more.current; const loadMore = more.current;
const ignoreRevision = force.current; const ignoreRevision = force.current;
const conversation = conversationId.current; const conversation = conversationId.current;
@ -53,6 +51,9 @@ console.log("SYNCING!", reset.current, update.current, force.current, more.curre
reset.current = false; reset.current = false;
loaded.current = false; loaded.current = false;
topics.current = new Map(); topics.current = new Map();
if (!conversation) {
updateState({ offsync: false, topics: topics.current, card: null, channel: null });
}
} }
if (conversation) { if (conversation) {
@ -74,9 +75,6 @@ console.log("SYNCING!", reset.current, update.current, force.current, more.curre
curTopicMarker.current = topicMarker; curTopicMarker.current = topicMarker;
loaded.current = true; loaded.current = true;
} }
else {
updateState({ card: cardValue, channel: channelValue });
}
} }
else { else {
console.log("failed to load conversation"); console.log("failed to load conversation");
@ -86,28 +84,25 @@ console.log("SYNCING!", reset.current, update.current, force.current, more.curre
try { try {
if (!curTopicMarker.current) { if (!curTopicMarker.current) {
console.log("FIRST GET");
const delta = await getTopicDelta(cardId, channelId, null, COUNT, null, null); const delta = await getTopicDelta(cardId, channelId, null, COUNT, null, null);
await setTopicDelta(cardId, channelId, delta.topics); await setTopicDelta(cardId, channelId, delta.topics);
await setMarkerAndSync(cardId, channelId, delta.marker, topicRevision); await setMarkerAndSync(cardId, channelId, delta.marker, topicRevision);
curTopicMarker.current = delta.marker; curTopicMarker.current = delta.marker;
console.log("---", delta);
curSyncRevision.current = topicRevision; curSyncRevision.current = topicRevision;
} }
if (loadMore && marker) { if (loadMore && marker) {
console.log("MORE GET");
const delta = await getTopicDelta(cardId, channelId, null, COUNT, null, curTopicMarker.current); const delta = await getTopicDelta(cardId, channelId, null, COUNT, null, curTopicMarker.current);
await setTopicDelta(cardId, channelId, delta.topics); await setTopicDelta(cardId, channelId, delta.topics);
await setTopicMarker(cardId, channelId, delta.marker); await setTopicMarker(cardId, channelId, delta.marker);
curTopicMarker.current = delta.marker; curTopicMarker.current = delta.marker;
} }
if (ignoreRevision || topicRevision !== curSyncRevision.current) { if (ignoreRevision || topicRevision !== curSyncRevision.current) {
console.log("UPDATE"); const delta = await getTopicDelta(cardId, channelId, curSyncRevision.current, null, curTopicMarker.current, null);
const delta = await getTopicDelta(cardId, channelId, curSyncRevision.currnet, null, curTopicMarker.current, null);
await setTopicDelta(cardId, channelId, delta.topics); await setTopicDelta(cardId, channelId, delta.topics);
await setSyncRevision(cardId, channelId, topicRevision); await setSyncRevision(cardId, channelId, topicRevision);
curSyncRevision.current = topicRevision; curSyncRevision.current = topicRevision;
} }
updateState({ offsync: false, topics: topics.current, card: cardValue, channel: channelValue });
} }
catch(err) { catch(err) {
console.log(err); console.log(err);
@ -132,7 +127,7 @@ console.log("UPDATE");
} }
else { else {
const topic = await getTopic(cardId, channelId, entry.id); const topic = await getTopic(cardId, channelId, entry.id);
const item = mapTopicEntry(entry); const item = mapTopicEntry(topic);
setTopicItem(cardId, channelId, item); setTopicItem(cardId, channelId, item);
topics.current.set(item.topicId, item); topics.current.set(item.topicId, item);
} }
@ -142,7 +137,6 @@ console.log("UPDATE");
clearTopicItem(entry.id); clearTopicItem(entry.id);
} }
} }
updateState({ offsync: false, topics: topics.current });
} }
useEffect(() => { useEffect(() => {
@ -153,13 +147,11 @@ console.log("UPDATE");
const actions = { const actions = {
setConversation: async (cardId, channelId) => { setConversation: async (cardId, channelId) => {
console.log(">>> SET");
conversationId.current = { cardId, channelId }; conversationId.current = { cardId, channelId };
reset.current = true; reset.current = true;
await sync(); await sync();
}, },
clearConversation: async () => { clearConversation: async () => {
console.log(">>> CLEAR");
conversationId.current = null; conversationId.current = null;
reset.current = true; reset.current = true;
await sync(); await sync();
@ -285,7 +277,7 @@ console.log(">>> CLEAR");
else if (channelId) { else if (channelId) {
await channel.actions.setUnsealedTopicSubject(channelId, topicId, revision, unsealed); await channel.actions.setUnsealedTopicSubject(channelId, topicId, revision, unsealed);
} }
setTopicField(topicId, 'unsaledDetail', unsealed); setTopicField(topicId, 'unsealedDetail', unsealed);
}, },
setTopicSubject: async (topicId, type, subject) => { setTopicSubject: async (topicId, type, subject) => {
const { cardId, channelId } = conversationId.current || {}; const { cardId, channelId } = conversationId.current || {};

View File

@ -1,7 +1,7 @@
import { useEffect, useState, useRef, useContext } from 'react'; import { useEffect, useState, useRef, useContext } from 'react';
import SQLite from "react-native-sqlite-storage"; import SQLite from "react-native-sqlite-storage";
const DATABAG_DB = 'db_v_114.db'; const DATABAG_DB = 'db_v_115.db';
export function useStoreContext() { export function useStoreContext() {
const [state, setState] = useState({}); const [state, setState] = useState({});

View File

@ -43,11 +43,11 @@ export function Session() {
const screenParams = { headerShown: true, headerTintColor: Colors.primary }; const screenParams = { headerShown: true, headerTintColor: Colors.primary };
const ConversationStackScreen = () => { const ConversationStackScreen = () => {
const conversation = useContext(ConversationContext);
const [cardId, setCardId] = useState(); const [cardId, setCardId] = useState();
const [channelId, setChannelId] = useState(); const [channelId, setChannelId] = useState();
const openConversation = (navigation, card, channel) => {
const setConversation = (card, channel) => {
(async () => { (async () => {
conversation.actions.setConversation(card, channel); conversation.actions.setConversation(card, channel);
setCardId(card); setCardId(card);
@ -55,13 +55,17 @@ export function Session() {
navigation.navigate('conversation'); navigation.navigate('conversation');
})(); })();
}; };
const closeConversation = () => { const clearConversation = (navigation) => {
console.log("CLOSE CALLED!");
conversation.actions.clearConversation(); conversation.actions.clearConversation();
setCardId(null); setCardId(null);
setChannelId(null); setChannelId(null);
navigation.popToTop(); navigation.popToTop();
}; };
const closeConversation = () => {
conversation.actions.clearConversation();
setCardId(null);
setChannelId(null);
}
const openDetails = (navigation) => { const openDetails = (navigation) => {
navigation.navigate('details'); navigation.navigate('details');
@ -75,13 +79,13 @@ export function Session() {
</ConversationStack.Screen> </ConversationStack.Screen>
<ConversationStack.Screen name="conversation" options={stackParams}> <ConversationStack.Screen name="conversation" options={stackParams}>
{(props) => <Conversation navigation={props.navigation} openDetails={() => openDetails(props.navigation)} closeConversation={closeConversation} /> } {(props) => <Conversation navigation={props.navigation} openDetails={() => openDetails(props.navigation)} closeConversation={(pop) => closeConversation(props.navigation, pop)} /> }
</ConversationStack.Screen> </ConversationStack.Screen>
<ConversationStack.Screen name="details" options={{ ...stackParams, headerTitle: (props) => ( <ConversationStack.Screen name="details" options={{ ...stackParams, headerTitle: (props) => (
<Text style={styles.headertext}>Details</Text> <Text style={styles.headertext}>Details</Text>
)}}> )}}>
{(props) => <Details clearConversation={() => closeConversation(props.navigation)} />} {(props) => <Details clearConversation={() => clearConversation(props.navigation)} />}
</ConversationStack.Screen> </ConversationStack.Screen>
</ConversationStack.Navigator> </ConversationStack.Navigator>
@ -162,7 +166,6 @@ export function Session() {
})(); })();
}; };
const closeConversation = () => { const closeConversation = () => {
console.log("CLOSE CALLED!");
conversation.actions.clearConversation(); conversation.actions.clearConversation();
setCardId(null); setCardId(null);
setChannelId(null); setChannelId(null);

View File

@ -14,9 +14,9 @@ import { AudioAsset } from './audioAsset/AudioAsset';
import { VideoAsset } from './videoAsset/VideoAsset'; import { VideoAsset } from './videoAsset/VideoAsset';
import Carousel from 'react-native-reanimated-carousel'; import Carousel from 'react-native-reanimated-carousel';
export function TopicItem({ item, focused, focus, hosting, sealed, sealKey, remove, update, block, report }) { export function TopicItem({ item, focused, focus, hosting, remove, update, block, report, contentKey }) {
const { state, actions } = useTopicItem(item, hosting, remove, sealed, sealKey); const { state, actions } = useTopicItem(item, hosting, remove, contentKey);
const erase = () => { const erase = () => {
Alert.alert( Alert.alert(

View File

@ -2,12 +2,14 @@ import { useState, useEffect, useContext } from 'react';
import { ConversationContext } from 'context/ConversationContext'; import { ConversationContext } from 'context/ConversationContext';
import { CardContext } from 'context/CardContext'; import { CardContext } from 'context/CardContext';
import { ProfileContext } from 'context/ProfileContext'; import { ProfileContext } from 'context/ProfileContext';
import { AccountContext } from 'context/AccountContext';
import moment from 'moment'; import moment from 'moment';
import { useWindowDimensions } from 'react-native'; import { useWindowDimensions } from 'react-native';
import Colors from 'constants/Colors'; import Colors from 'constants/Colors';
import { getCardByGuid } from 'context/cardUtil'; import { getCardByGuid } from 'context/cardUtil';
import { getChannelSeals, isUnsealed, getContentKey, decryptTopicSubject } from 'context/sealUtil';
export function useTopicItem(item, hosting, remove, sealed, sealKey) { export function useTopicItem(item, hosting, remove, contentKey) {
const [state, setState] = useState({ const [state, setState] = useState({
name: null, name: null,
@ -31,6 +33,7 @@ export function useTopicItem(item, hosting, remove, sealed, sealKey) {
const conversation = useContext(ConversationContext); const conversation = useContext(ConversationContext);
const profile = useContext(ProfileContext); const profile = useContext(ProfileContext);
const card = useContext(CardContext); const card = useContext(CardContext);
const account = useContext(AccountContext);
const dimensions = useWindowDimensions(); const dimensions = useWindowDimensions();
const updateState = (value) => { const updateState = (value) => {
@ -42,8 +45,9 @@ export function useTopicItem(item, hosting, remove, sealed, sealKey) {
}, [dimensions]); }, [dimensions]);
useEffect(() => { useEffect(() => {
const { topicId, detail, unsealedDetail } = item;
const { guid, dataType, data, status, transform } = detail; const { topicId, revision, detail, unsealedDetail } = item;
const { guid, created, dataType, data, status, transform } = detail || {};
let name, nameSet, known, logo; let name, nameSet, known, logo;
const identity = profile.state?.identity; const identity = profile.state?.identity;
@ -135,13 +139,13 @@ export function useTopicItem(item, hosting, remove, sealed, sealKey) {
} }
} }
else { else {
conversation.actions.unsealTopic(topicId, sealKey);
sealed = true; sealed = true;
unsealTopic(topicId, revision, detail);
} }
} }
let timestamp; let timestamp;
const date = new Date(item.detail.created * 1000); const date = new Date(created * 1000);
const now = new Date(); const now = new Date();
const offset = now.getTime() - date.getTime(); const offset = now.getTime() - date.getTime();
if(offset < 86400000) { if(offset < 86400000) {
@ -154,11 +158,27 @@ export function useTopicItem(item, hosting, remove, sealed, sealKey) {
timestamp = moment(date).format('M/DD/YYYY'); timestamp = moment(date).format('M/DD/YYYY');
} }
const editable = detail.guid === identity.guid && parsed; const editable = guid === identity?.guid && parsed;
const deletable = editable || hosting; const deletable = editable || hosting;
updateState({ logo, name, nameSet, known, sealed, message, fontSize, fontColor, timestamp, transform, status, assets, deletable, editable, editData: parsed, editMessage: message }); updateState({ logo, name, nameSet, known, sealed, message, fontSize, fontColor, timestamp, transform, status, assets, deletable, editable, editData: parsed, editMessage: message });
}, [sealKey, card, item]); }, [conversation.state, card.state, account.state, item]);
const unsealTopic = async (topicId, revision, topicDetail) => {
try {
const channelDetail = conversation.state.channel?.detail;
const seals = getChannelSeals(channelDetail?.data);
const sealKey = account.state.sealKey;
if (isUnsealed(seals, sealKey)) {
const contentKey = await getContentKey(seals, sealKey);
const unsealed = decryptTopicSubject(topicDetail.data, contentKey);
await conversation.actions.unsealTopic(topicId, revision, unsealed);
}
}
catch(err) {
console.log(err);
}
};
const actions = { const actions = {
showCarousel: (index) => { showCarousel: (index) => {

View File

@ -1,6 +1,7 @@
import { useEffect, useState, useContext } from 'react'; import { useEffect, useState, useContext, useRef } from 'react';
import { ProfileContext } from 'context/ProfileContext'; import { ProfileContext } from 'context/ProfileContext';
import { CardContext } from 'context/CardContext'; import { CardContext } from 'context/CardContext';
import { AccountContext } from 'context/AccountContext';
import { ConversationContext } from 'context/ConversationContext'; import { ConversationContext } from 'context/ConversationContext';
import { getChannelSubjectLogo } from 'context/channelUtil'; import { getChannelSubjectLogo } from 'context/channelUtil';
@ -17,6 +18,7 @@ export function useConversation() {
const profile = useContext(ProfileContext); const profile = useContext(ProfileContext);
const card = useContext(CardContext); const card = useContext(CardContext);
const conversation = useContext(ConversationContext); const conversation = useContext(ConversationContext);
const account = useContext(AccountContext);
useEffect(() => { useEffect(() => {
const cardId = conversation.state.card?.cardId; const cardId = conversation.state.card?.cardId;
@ -41,9 +43,7 @@ export function useConversation() {
const filtered = sorted.filter(item => !(item.blocked === 1)); const filtered = sorted.filter(item => !(item.blocked === 1));
updateState({ logo, subject, topics: filtered }); updateState({ logo, subject, topics: filtered });
}, [conversation.state, profile.state]);
console.log("UPDATE TOPICS", filtered.length);
}, [conversation.state, card.state, profile.state]);
const actions = {}; const actions = {};

View File

@ -40,12 +40,19 @@ export function useDetails() {
setState((s) => ({ ...s, ...value })); setState((s) => ({ ...s, ...value }));
} }
useEffect(() => {
(async () => {
const notification = await conversation.actions.getNotifications();
updateState({ notification });
})();
}, []);
useEffect(() => { useEffect(() => {
let locked; let locked;
let unlocked; let unlocked;
let seals; let seals;
let sealKey; let sealKey;
const { channel, notification } = conversation.state; const { channel } = conversation.state;
if (channel?.detail?.dataType === 'sealed') { if (channel?.detail?.dataType === 'sealed') {
locked = true; locked = true;
try { try {
@ -62,7 +69,7 @@ export function useDetails() {
locked = false; locked = false;
unlocked = false; unlocked = false;
} }
updateState({ locked, unlocked, seals, sealKey, notification }); updateState({ locked, unlocked, seals, sealKey });
}, [account.state, conversation.state]); }, [account.state, conversation.state]);
const setMemberItem = (contact, guids) => { const setMemberItem = (contact, guids) => {
@ -223,6 +230,7 @@ export function useDetails() {
}, },
setNotifications: async (notification) => { setNotifications: async (notification) => {
await conversation.actions.setNotifications(notification); await conversation.actions.setNotifications(notification);
updateState({ notification });
}, },
}; };