mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 12:39:17 +00:00
support resyncing of contacts
This commit is contained in:
parent
cb544071ce
commit
43bf6d0d04
@ -310,7 +310,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 18;
|
||||
CURRENT_PROJECT_VERSION = 19;
|
||||
DEVELOPMENT_TEAM = 3P65PQ7SUR;
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
@ -348,7 +348,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 18;
|
||||
CURRENT_PROJECT_VERSION = 19;
|
||||
DEVELOPMENT_TEAM = 3P65PQ7SUR;
|
||||
INFOPLIST_FILE = Databag/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Databag;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useState, useRef, useContext } from 'react';
|
||||
import { StoreContext } from 'context/StoreContext';
|
||||
import { UploadContext } from 'context/UploadContext';
|
||||
import { getCard } from 'api/getCard';
|
||||
import { getCards } from 'api/getCards';
|
||||
import { getCardProfile } from 'api/getCardProfile';
|
||||
import { setCardProfile } from 'api/setCardProfile';
|
||||
@ -42,15 +43,16 @@ export function useCardContext() {
|
||||
const syncing = useRef(false);
|
||||
const cards = useRef(new Map());
|
||||
const cardChannels = useRef(new Map());
|
||||
const resync = useRef([]);
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }))
|
||||
}
|
||||
|
||||
const getCard = (cardId) => {
|
||||
const getCardEntry = (cardId) => {
|
||||
const card = cards.current.get(cardId);
|
||||
if (!card) {
|
||||
throw new Error('cared not found');
|
||||
throw new Error('card not found');
|
||||
}
|
||||
return card;
|
||||
}
|
||||
@ -213,12 +215,12 @@ export function useCardContext() {
|
||||
}
|
||||
|
||||
const sync = async () => {
|
||||
if (!syncing.current && setRevision.current !== curRevision.current) {
|
||||
if (!syncing.current && (setRevision.current !== curRevision.current || resync.current.length > 0)) {
|
||||
syncing.current = true;
|
||||
const { server, appToken, guid } = session.current;
|
||||
|
||||
try {
|
||||
const revision = curRevision.current;
|
||||
const { server, appToken, guid } = session.current;
|
||||
|
||||
// get and store
|
||||
const delta = await getCards(server, appToken, setRevision.current);
|
||||
@ -254,41 +256,7 @@ export function useCardContext() {
|
||||
}
|
||||
}
|
||||
|
||||
const status = await store.actions.getCardItemStatus(guid, card.id);
|
||||
const cardServer = status.profile.node;
|
||||
const cardToken = status.profile.guid + '.' + status.detail.token;
|
||||
if (status.detail.status === 'connected') {
|
||||
try {
|
||||
const { notifiedView, notifiedProfile, notifiedArticle, notifiedChannel } = card.data;
|
||||
if (status.notifiedView !== notifiedView) {
|
||||
await store.actions.clearCardChannelItems(guid, card.id);
|
||||
await updateCardChannelItems(card.id, cardServer, cardToken, notifiedView, null);
|
||||
await store.actions.setCardItemNotifiedChannel(guid, card.id, notifiedChannel);
|
||||
await store.actions.setCardItemNotifiedView(guid, card.id, notifiedView);
|
||||
clearCardChannel(card.id);
|
||||
}
|
||||
else {
|
||||
if (status.notifiedChannel != notifiedChannel) {
|
||||
await updateCardChannelItems(card.id, cardServer, cardToken, status.notifiedView, status.notifiedChannel)
|
||||
await store.actions.setCardItemNotifiedChannel(guid, card.id, notifiedChannel);
|
||||
}
|
||||
}
|
||||
if (status.notifiedProfile != notifiedProfile) {
|
||||
const message = await getContactProfile(cardServer, cardToken);
|
||||
await setCardProfile(server, appToken, card.id, message);
|
||||
await store.actions.setCardItemNotifiedProfile(guid, card.id, notifiedProfile);
|
||||
}
|
||||
if (status.offsync) {
|
||||
await store.actions.clearCardItemOffsync(guid, card.id);
|
||||
setCardOffsync(card.id, false);
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
console.log("card1:", err);
|
||||
await store.actions.setCardItemOffsync(guid, card.id);
|
||||
setCardOffsync(card.id, true);
|
||||
}
|
||||
}
|
||||
await syncCard(card);
|
||||
}
|
||||
else {
|
||||
//TODO clear card channel topics
|
||||
@ -307,12 +275,65 @@ export function useCardContext() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (resync.current.length > 0) {
|
||||
const ids = resync.current;
|
||||
resync.current = [];
|
||||
|
||||
for(let i = 0; i < ids.length; i++) {
|
||||
const item = cards.current.get(ids[i]);
|
||||
if (item) {
|
||||
const card = await getCard(server, appToken, ids[i]);
|
||||
await syncCard(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateState({ cards: cards.current });
|
||||
syncing.current = false;
|
||||
sync();
|
||||
}
|
||||
};
|
||||
|
||||
const syncCard = async (card) => {
|
||||
|
||||
const { server, appToken, guid } = session.current;
|
||||
const status = await store.actions.getCardItemStatus(guid, card.id);
|
||||
const cardServer = status.profile.node;
|
||||
const cardToken = status.profile.guid + '.' + status.detail.token;
|
||||
if (status.detail.status === 'connected') {
|
||||
try {
|
||||
const { notifiedView, notifiedProfile, notifiedArticle, notifiedChannel } = card.data;
|
||||
if (status.notifiedView !== notifiedView) {
|
||||
await store.actions.clearCardChannelItems(guid, card.id);
|
||||
await updateCardChannelItems(card.id, cardServer, cardToken, notifiedView, null);
|
||||
await store.actions.setCardItemNotifiedChannel(guid, card.id, notifiedChannel);
|
||||
await store.actions.setCardItemNotifiedView(guid, card.id, notifiedView);
|
||||
clearCardChannel(card.id);
|
||||
}
|
||||
else {
|
||||
if (status.notifiedChannel != notifiedChannel) {
|
||||
await updateCardChannelItems(card.id, cardServer, cardToken, status.notifiedView, status.notifiedChannel)
|
||||
await store.actions.setCardItemNotifiedChannel(guid, card.id, notifiedChannel);
|
||||
}
|
||||
}
|
||||
if (status.notifiedProfile != notifiedProfile) {
|
||||
const message = await getContactProfile(cardServer, cardToken);
|
||||
await setCardProfile(server, appToken, card.id, message);
|
||||
await store.actions.setCardItemNotifiedProfile(guid, card.id, notifiedProfile);
|
||||
}
|
||||
if (status.offsync) {
|
||||
await store.actions.clearCardItemOffsync(guid, card.id);
|
||||
setCardOffsync(card.id, 0);
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
console.log("card1:", err);
|
||||
await store.actions.setCardItemOffsync(guid, card.id);
|
||||
setCardOffsync(card.id, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const updateCardChannelItems = async (cardId, cardServer, cardToken, notifiedView, notifiedChannel) => {
|
||||
const { guid } = session.current;
|
||||
const delta = await getContactChannels(cardServer, cardToken, notifiedView, notifiedChannel);
|
||||
@ -501,19 +522,19 @@ export function useCardContext() {
|
||||
return await store.actions.clearCardChannelTopicItems(guid, cardId, channelId);
|
||||
},
|
||||
getChannelTopic: async (cardId, channelId, topicId) => {
|
||||
const { detail, profile } = getCard(cardId);
|
||||
const { detail, profile } = getCardEntry(cardId);
|
||||
return await getContactChannelTopic(profile.node, `${profile.guid}.${detail.token}`, channelId, topicId);
|
||||
},
|
||||
getChannelTopics: async (cardId, channelId, revision) => {
|
||||
const { detail, profile } = getCard(cardId);
|
||||
const { detail, profile } = getCardEntry(cardId);
|
||||
return await getContactChannelTopics(profile.node, `${profile.guid}.${detail.token}`, channelId, revision);
|
||||
},
|
||||
getChannelTopicAssetUrl: (cardId, channelId, topicId, assetId) => {
|
||||
const { detail, profile } = getCard(cardId);
|
||||
const { detail, profile } = getCardEntry(cardId);
|
||||
return getContactChannelTopicAssetUrl(profile.node, `${profile.guid}.${detail.token}`, channelId, topicId, assetId);
|
||||
},
|
||||
addChannelTopic: async (cardId, channelId, message, files) => {
|
||||
const { detail, profile } = getCard(cardId);
|
||||
const { detail, profile } = getCardEntry(cardId);
|
||||
const node = profile.node;
|
||||
const token = `${profile.guid}.${detail.token}`;
|
||||
if (files?.length > 0) {
|
||||
@ -535,17 +556,21 @@ export function useCardContext() {
|
||||
}
|
||||
},
|
||||
setChannelTopicSubject: async (cardId, channelId, topicId, data) => {
|
||||
const { detail, profile } = getCard(cardId);
|
||||
const { detail, profile } = getCardEntry(cardId);
|
||||
return await setContactChannelTopicSubject(profile.node, `${profile.guid}.${detail.token}`, channelId, topicId, data);
|
||||
},
|
||||
removeChannel: async (cardId, channelId) => {
|
||||
const { detail, profile } = getCard(cardId);
|
||||
const { detail, profile } = getCardEntry(cardId);
|
||||
return await removeContactChannel(profile.node, `${profile.guid}.${detail.token}`, channelId);
|
||||
},
|
||||
removeChannelTopic: async (cardId, channelId, topicId) => {
|
||||
const { detail, profile } = getCard(cardId);
|
||||
const { detail, profile } = getCardEntry(cardId);
|
||||
return await removeContactChannelTopic(profile.node, `${profile.guid}.${detail.token}`, channelId, topicId);
|
||||
},
|
||||
resync: (cardId) => {
|
||||
resync.current.push(cardId);
|
||||
sync();
|
||||
},
|
||||
}
|
||||
|
||||
return { state, actions }
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useEffect, useState, useRef, useContext } from 'react';
|
||||
import SQLite from "react-native-sqlite-storage";
|
||||
|
||||
const DATABAG_DB = 'databag_v046.db';
|
||||
const DATABAG_DB = 'databag_v047.db';
|
||||
|
||||
export function useStoreContext() {
|
||||
const [state, setState] = useState({});
|
||||
|
@ -20,7 +20,10 @@ export function CardItem({ item, openContact }) {
|
||||
<Text style={styles.name} numberOfLines={1} ellipsizeMode={'tail'}>{ item.name }</Text>
|
||||
<Text style={styles.handle} numberOfLines={1} ellipsizeMode={'tail'}>{ item.handle }</Text>
|
||||
</View>
|
||||
{ item.status === 'connected' && (
|
||||
{ item.status === 'connected' && item.offsync === 1 && (
|
||||
<View style={styles.offsync} />
|
||||
)}
|
||||
{ item.status === 'connected' && item.offsync !== 1 && (
|
||||
<View style={styles.connected} />
|
||||
)}
|
||||
{ item.status === 'requested' && (
|
||||
|
@ -48,6 +48,12 @@ export const styles = StyleSheet.create({
|
||||
borderRadius: 4,
|
||||
backgroundColor: Colors.connecting,
|
||||
},
|
||||
offsync: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
backgroundColor: Colors.error,
|
||||
},
|
||||
pending: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
|
@ -31,7 +31,7 @@ export function useCards() {
|
||||
|
||||
const setCardItem = (item) => {
|
||||
const { profile, detail } = item;
|
||||
|
||||
|
||||
return {
|
||||
cardId: item.cardId,
|
||||
name: profile.name,
|
||||
@ -39,6 +39,7 @@ export function useCards() {
|
||||
status: detail.status,
|
||||
offsync: item.offsync,
|
||||
blocked: item.blocked,
|
||||
offsync: item.offsync,
|
||||
updated: detail.statusUpdated,
|
||||
logo: profile.imageSet ? card.actions.getCardLogo(item.cardId, profile.revision) : 'avatar',
|
||||
}
|
||||
|
@ -9,7 +9,18 @@ import Colors from 'constants/Colors';
|
||||
|
||||
export function ContactTitle({ contact, closeContact }) {
|
||||
const { state, actions } = useContact(contact, closeContact);
|
||||
return (<Text style={styles.title}>{ `${state.handle}@${state.node}` }</Text>);
|
||||
|
||||
return (
|
||||
<TouchableOpacity style={styles.resync} activeOpacity={1} onPress={actions.resync}>
|
||||
<View style={styles.icon} />
|
||||
<Text style={styles.title}>{ `${state.handle}@${state.node}` }</Text>
|
||||
<View style={styles.icon}>
|
||||
{ state.offsync === 1 && (
|
||||
<Ionicons name="exclamationcircleo" size={16} color={Colors.alert} />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
export function Contact({ contact, closeContact }) {
|
||||
|
@ -18,6 +18,16 @@ export const styles = StyleSheet.create({
|
||||
title: {
|
||||
fontSize: 18,
|
||||
},
|
||||
resync: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
icon: {
|
||||
width: 32,
|
||||
paddingLeft: 8
|
||||
},
|
||||
drawer: {
|
||||
paddingTop: 16,
|
||||
},
|
||||
|
@ -18,7 +18,8 @@ export function useContact(contact, close) {
|
||||
status: null,
|
||||
cardId: null,
|
||||
guid: null,
|
||||
busy: false
|
||||
busy: false,
|
||||
offsync: false,
|
||||
});
|
||||
|
||||
const dimensions = useWindowDimensions();
|
||||
@ -42,10 +43,10 @@ export function useContact(contact, close) {
|
||||
if (contact?.card) {
|
||||
const selected = card.state.cards.get(contact.card);
|
||||
if (selected) {
|
||||
const { profile, detail, cardId } = selected;
|
||||
const { offsync, profile, detail, cardId } = selected;
|
||||
const { name, handle, node, location, description, guid, imageSet, revision } = profile;
|
||||
const logo = imageSet ? card.actions.getCardLogo(cardId, revision) : 'avatar';
|
||||
updateState({ name, handle, node, location, description, logo, cardId, guid, status: detail.status });
|
||||
updateState({ offsync, name, handle, node, location, description, logo, cardId, guid, status: detail.status });
|
||||
stateSet = true;
|
||||
}
|
||||
}
|
||||
@ -56,12 +57,12 @@ export function useContact(contact, close) {
|
||||
const { cardId, profile, detail } = selected;
|
||||
const { name, handle, node, location, description, guid, imageSet, revision } = profile;
|
||||
const logo = imageSet ? card.actions.getCardLogo(cardId, revision) : 'avatar';
|
||||
updateState({ name, handle, node, location, description, logo, cardId, guid, status: detail.status });
|
||||
updateState({ offsync, name, handle, node, location, description, logo, cardId, guid, status: detail.status });
|
||||
stateSet = true;
|
||||
}
|
||||
else {
|
||||
const { name, handle, node, location, description, logo, guid } = contact.account;
|
||||
updateState({ name, handle, node, location, description, logo, guid, cardId: null, status: null });
|
||||
updateState({ offsync: false, name, handle, node, location, description, logo, guid, cardId: null, status: null });
|
||||
stateSet = true;
|
||||
}
|
||||
}
|
||||
@ -176,6 +177,9 @@ export function useContact(contact, close) {
|
||||
close();
|
||||
});
|
||||
},
|
||||
resync: () => {
|
||||
card.actions.resync(contact.card);
|
||||
},
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
|
Loading…
Reference in New Issue
Block a user