mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
rendering contact request status
This commit is contained in:
parent
b2ce79a290
commit
8848152a5d
@ -29,6 +29,7 @@ import { removeContactChannelTopic } from 'api/removeContactChannelTopic';
|
|||||||
export function useCardContext() {
|
export function useCardContext() {
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
cards: new Map(),
|
cards: new Map(),
|
||||||
|
requestRevision: null,
|
||||||
});
|
});
|
||||||
const store = useContext(StoreContext);
|
const store = useContext(StoreContext);
|
||||||
const upload = useContext(UploadContext);
|
const upload = useContext(UploadContext);
|
||||||
@ -356,6 +357,8 @@ export function useCardContext() {
|
|||||||
setSession: async (access) => {
|
setSession: async (access) => {
|
||||||
const { guid, server, appToken } = access;
|
const { guid, server, appToken } = access;
|
||||||
cards.current = new Map();
|
cards.current = new Map();
|
||||||
|
const status = await store.actions.getCardRequestStatus(guid);
|
||||||
|
updateState({ requestRevision: status.revision });
|
||||||
const cardItems = await store.actions.getCardItems(guid);
|
const cardItems = await store.actions.getCardItems(guid);
|
||||||
for (item of cardItems) {
|
for (item of cardItems) {
|
||||||
cards.current.set(item.cardId, { ...item, channels: new Map() });
|
cards.current.set(item.cardId, { ...item, channels: new Map() });
|
||||||
@ -370,6 +373,11 @@ export function useCardContext() {
|
|||||||
curRevision.current = revision;
|
curRevision.current = revision;
|
||||||
session.current = access;
|
session.current = access;
|
||||||
},
|
},
|
||||||
|
setRequestRevision: async (revision) => {
|
||||||
|
const { guid } = session.current
|
||||||
|
await store.actions.setCardRequestStatus(guid, { revision });
|
||||||
|
updateState({ requestRevision: revision });
|
||||||
|
},
|
||||||
clearSession: () => {
|
clearSession: () => {
|
||||||
session.current = {};
|
session.current = {};
|
||||||
updateState({ account: null });
|
updateState({ account: null });
|
||||||
|
@ -44,6 +44,14 @@ export function useStoreContext() {
|
|||||||
const dataId = `${guid}_profile`;
|
const dataId = `${guid}_profile`;
|
||||||
await db.current.executeSql("INSERT OR REPLACE INTO app (key, value) values (?, ?);", [dataId, encodeObject(profile)]);
|
await db.current.executeSql("INSERT OR REPLACE INTO app (key, value) values (?, ?);", [dataId, encodeObject(profile)]);
|
||||||
},
|
},
|
||||||
|
getCardRequestStatus: async (guid) => {
|
||||||
|
const dataId = `${guid}_card_status`;
|
||||||
|
return await getAppValue(db.current, dataId, {});
|
||||||
|
},
|
||||||
|
setCardRequestStatus: async (guid, status) => {
|
||||||
|
const dataId = `${guid}_card_status`;
|
||||||
|
await db.current.executeSql("INSERT OR REPLACE INTO app (key, value) values (?, ?);", [dataId, encodeObject(status)]);
|
||||||
|
},
|
||||||
getProfileRevision: async (guid) => {
|
getProfileRevision: async (guid) => {
|
||||||
const dataId = `${guid}_profileRevision`;
|
const dataId = `${guid}_profileRevision`;
|
||||||
return await getAppValue(db.current, dataId, null);
|
return await getAppValue(db.current, dataId, null);
|
||||||
|
@ -23,6 +23,7 @@ import { useChannels } from './channels/useChannels.hook';
|
|||||||
import { CommonActions } from '@react-navigation/native';
|
import { CommonActions } from '@react-navigation/native';
|
||||||
import { ConversationContext } from 'context/ConversationContext';
|
import { ConversationContext } from 'context/ConversationContext';
|
||||||
import { ProfileIcon } from './profileIcon/ProfileIcon';
|
import { ProfileIcon } from './profileIcon/ProfileIcon';
|
||||||
|
import { CardsIcon } from './cardsIcon/CardsIcon';
|
||||||
|
|
||||||
const ConversationStack = createStackNavigator();
|
const ConversationStack = createStackNavigator();
|
||||||
const ProfileStack = createStackNavigator();
|
const ProfileStack = createStackNavigator();
|
||||||
@ -201,8 +202,8 @@ export function Session() {
|
|||||||
<Text style={styles.profileLabel}>Profile</Text>
|
<Text style={styles.profileLabel}>Profile</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity style={styles.option} onPress={openCards}>
|
<TouchableOpacity style={styles.option} onPress={openCards}>
|
||||||
<Ionicons style={styles.icon} name={'contacts'} size={20} />
|
<CardsIcon color={Colors.text} size={20} />
|
||||||
<Text>Contacts</Text>
|
<Text style={styles.profileLabel}>Contacts</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
<View style={styles.channels}>
|
<View style={styles.channels}>
|
||||||
@ -337,6 +338,8 @@ export function Session() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [cardsActive, setCardsActive] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
{ state.tabbed === false && (
|
{ state.tabbed === false && (
|
||||||
@ -349,6 +352,7 @@ export function Session() {
|
|||||||
)}
|
)}
|
||||||
{ state.tabbed === true && (
|
{ state.tabbed === true && (
|
||||||
<Tab.Navigator
|
<Tab.Navigator
|
||||||
|
screenListeners={{ state: (e) => setCardsActive(e?.data?.state?.index === 2) }}
|
||||||
screenOptions={({ route }) => ({
|
screenOptions={({ route }) => ({
|
||||||
tabBarStyle: styles.tabBar,
|
tabBarStyle: styles.tabBar,
|
||||||
headerShown: false,
|
headerShown: false,
|
||||||
@ -360,7 +364,7 @@ export function Session() {
|
|||||||
return <Ionicons name={'message1'} size={size} color={color} />;
|
return <Ionicons name={'message1'} size={size} color={color} />;
|
||||||
}
|
}
|
||||||
if (route.name === 'Contacts') {
|
if (route.name === 'Contacts') {
|
||||||
return <Ionicons name={'contacts'} size={size} color={color} />;
|
return <CardsIcon size={size} color={color} active={cardsActive} />;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tabBarShowLabel: false,
|
tabBarShowLabel: false,
|
||||||
|
19
app/mobile/src/session/cardsIcon/CardsIcon.jsx
Normal file
19
app/mobile/src/session/cardsIcon/CardsIcon.jsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { View } from 'react-native';
|
||||||
|
import { useCardsIcon } from './useCardsIcon.hook';
|
||||||
|
import { styles } from './CardsIcon.styled';
|
||||||
|
import Ionicons from '@expo/vector-icons/AntDesign';
|
||||||
|
|
||||||
|
export function CardsIcon({ size, color, active }) {
|
||||||
|
|
||||||
|
const { state, actions } = useCardsIcon(active);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Ionicons name={'contacts'} size={size} color={color} />
|
||||||
|
{ state.curRevision !== state.setRevision && (
|
||||||
|
<View style={styles.requested} />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
14
app/mobile/src/session/cardsIcon/CardsIcon.styled.js
Normal file
14
app/mobile/src/session/cardsIcon/CardsIcon.styled.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
import { Colors } from 'constants/Colors';
|
||||||
|
|
||||||
|
export const styles = StyleSheet.create({
|
||||||
|
requested: {
|
||||||
|
width: 8,
|
||||||
|
height: 8,
|
||||||
|
borderRadius: 4,
|
||||||
|
backgroundColor: Colors.pending,
|
||||||
|
position: 'absolute',
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
},
|
||||||
|
});
|
43
app/mobile/src/session/cardsIcon/useCardsIcon.hook.js
Normal file
43
app/mobile/src/session/cardsIcon/useCardsIcon.hook.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { useState, useEffect, useContext } from 'react';
|
||||||
|
import { CardContext } from 'context/CardContext';
|
||||||
|
|
||||||
|
export function useCardsIcon(active) {
|
||||||
|
|
||||||
|
const [state, setState] = useState({
|
||||||
|
curRevision: null,
|
||||||
|
setRevision: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const card = useContext(CardContext);
|
||||||
|
|
||||||
|
const updateState = (value) => {
|
||||||
|
setState((s) => ({ ...s, ...value }));
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (active && state.curRevision) {
|
||||||
|
card.actions.setRequestRevision(state.curRevision);
|
||||||
|
}
|
||||||
|
}, [active]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let revision;
|
||||||
|
card.state.cards.forEach((contact) => {
|
||||||
|
if (contact?.detail?.status === 'pending' || contact?.detail?.status === 'requested') {
|
||||||
|
if (!revision || contact.detailRevision > revision) {
|
||||||
|
revision = contact.detailRevision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (active && revision !== state.setRevision) {
|
||||||
|
card.actions.setRequestRevision(state.curRevision);
|
||||||
|
}
|
||||||
|
updateState({ setRevision: card.state.requestRevision, curRevision: revision });
|
||||||
|
|
||||||
|
}, [card]);
|
||||||
|
|
||||||
|
const actions = {};
|
||||||
|
|
||||||
|
return { state, actions };
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user