refactoring contact screen

This commit is contained in:
balzack 2023-02-24 00:27:09 -08:00
parent c86f9f9948
commit b132e3494b
7 changed files with 192 additions and 17 deletions

View File

@ -11,8 +11,8 @@ import { styles } from './Session.styled';
import Colors from 'constants/Colors';
import { Profile, ProfileHeader, ProfileBody } from './profile/Profile';
import { CardsHeader, CardsBody, Cards } from './cards/Cards';
import { RegistryTitle, RegistryBody, Registry } from './registry/Registry';
import { Contact, ContactTitle } from './contact/Contact';
import { RegistryHeader, RegistryBody, Registry } from './registry/Registry';
import { ContactHeader, ContactBody, Contact } from './contact/Contact';
import { Details, DetailsHeader, DetailsBody } from './details/Details';
import { Conversation, ConversationHeader, ConversationBody } from './conversation/Conversation';
import { Welcome } from './welcome/Welcome';
@ -108,16 +108,18 @@ export function Session() {
<ContactStack.Navigator screenOptions={({ route }) => (screenParams)} initialRouteName="cards">
<ContactStack.Screen name="cards" options={{ ...stackParams, headerTitle: (props) => (
<CardsHeader filter={filter} setFilter={setFilter} sort={sort} setSort={setSort} openRegistry={() => openRegistry(props.navigation)} />
<CardsHeader filter={filter} setFilter={setFilter} sort={sort} setSort={setSort} openRegistry={openRegistry} />
)}}>
{(props) => <CardsBody filter={filter} sort={sort} openContact={(contact) => openContact(props.navigation, contact)} />}
</ContactStack.Screen>
<ContactStack.Screen name="contact" options={{ ...stackParams, headerTitle: (props) => <ContactTitle contact={contact} /> }}>
<ContactStack.Screen name="contact" options={{ ...stackParams, headerTitle: (props) => (
<ContactHeader contact={contact} />
)}}>
{(props) => <ContactBody contact={contact} />}
</ContactStack.Screen>
<ContactStack.Screen name="registry" options={{ ...stackParams, headerTitle: (props) => <RegistryTitle /> }}>
<ContactStack.Screen name="registry" options={{ ...stackParams, headerTitle: (props) => <RegistryHeader /> }}>
{(props) => <RegistryBody openContact={(contact) => openContact(props.navigation, contact)} />}
</ContactStack.Screen>

View File

@ -7,9 +7,10 @@ import AntIcons from 'react-native-vector-icons/AntDesign';
import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { Colors } from 'constants/Colors';
import { CardItem } from './cardItem/CardItem';
import { useNavigation } from '@react-navigation/native';
export function CardsHeader({ filter, setFilter, sort, setSort, openRegistry }) {
const { state, actions } = useCards(filter, sort);
const navigation = useNavigation();
return (
<View style={styles.title}>
@ -29,7 +30,7 @@ export function CardsHeader({ filter, setFilter, sort, setSort, openRegistry })
autoCapitalize="none" placeholderTextColor={Colors.disabled} placeholder="Contacts" />
<View style={styles.space} />
</View>
<TouchableOpacity style={styles.add} onPress={openRegistry}>
<TouchableOpacity style={styles.add} onPress={() => openRegistry(navigation)}>
<AntIcons name={'adduser'} size={16} color={Colors.white} style={[styles.box, { transform: [ { rotateY: "180deg" }, ]} ]}/>
<Text style={styles.newtext}>New</Text>
</TouchableOpacity>

View File

@ -5,7 +5,9 @@ import { styles } from './CardItem.styled';
export function CardItem({ item, openContact }) {
const select = () => {
openContact({ card: item.cardId });
const { guid, name, handle, node, location, description } = item;
const contact = { guid, name, handle, node, location, description };
openContact({ contact });
};
return (

View File

@ -15,17 +15,22 @@ export function useCards(filter, sort) {
const setCardItem = (item) => {
const { profile, detail, cardId } = item.card || { profile: {}, detail: {} }
const { name, handle, node, guid, location, description, imageSet } = profile;
return {
cardId: cardId,
name: profile.name,
handle: `${profile.handle}@${profile.node}`,
name: name,
handle: handle,
node: node,
guid: guid,
location: location,
description: description,
status: detail.status,
offsync: item.offsync,
blocked: item.blocked,
offsync: item.offsync,
updated: detail.statusUpdated,
logo: profile.imageSet ? card.actions.getCardImageUrl(cardId) : 'avatar',
logo: imageSet ? card.actions.getCardImageUrl(cardId) : 'avatar',
}
};

View File

@ -1,14 +1,20 @@
import { Text } from 'react-native';
export function ContactTitle({ contact, closeContact }) {
<Text>ContactTitle</Text>
export function ContactHeader({ contact, closeContact }) {
return (
<Text>ContactTitle</Text>
);
}
export function ContactBody({ contact }) {
<Text>ContactBody</Text>;
return (
<Text>ContactBody</Text>
);
}
export function Contact({ contact, closeContact }) {
<Text>Contact</Text>
return (
<Text>Contact</Text>
);
}

View File

@ -0,0 +1,159 @@
import { useState, useEffect, useRef, useContext } from 'react';
import { CardContext } from 'context/CardContext';
import { getListingMessage } from 'api/getListingMessage';
import { getListingImageUrl } from 'api/getListingImageUrl';
import { addFlag } from 'api/addFlag';
import { getCardByGuid } from 'context/cardUtils';
export function useContact(contact) {
const [state, setState] = useState({
name: null,
handle: null,
node: null,
location: null,
description: null,
logo: null,
status: null,
cardId: null,
guid: null,
busy: false,
offsync: false,
});
const card = useContext(CardContext);
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));
}
useEffect(() => {
const contactCard = getCardByGuid(contact.guid);
if (contactCard) {
const { offsync, profile, detail, cardId } = selected.card;
const { name, handle, node, location, description, guid, imageSet, revision } = profile;
const logo = imageSet ? card.actions.getCardImageUrl(cardId) : 'avatar';
updateState({ offsync, name, handle, node, location, description, logo, cardId, guid, status: detail.status });
}
else {
const { guid, handle, node, name, location, description, imageSet } = contact;
const logo = imageSet ? getListingImageUrl(node, guid) : 'avatar';
updateState({ guid, handle, node, name, location, description, logo, offsync: false, status: null });
}
}, [contact, card.state]);
const applyAction = async (action) => {
if (!state.busy) {
try {
updateState({ busy: true });
await action();
updateState({ busy: false });
}
catch (err) {
console.log(err);
updateState({ busy: false });
throw new Error("failed to update contact");
}
}
else {
throw new Error("operation in progress");
}
}
const actions = {
saveAndConnect: async () => {
await applyAction(async () => {
let profile = await getListingMessage(state.node, state.guid);
let added = await card.actions.addCard(profile);
await card.actions.setCardConnecting(added.id);
let open = await card.actions.getCardOpenMessage(added.id);
let contact = await card.actions.setCardOpenMessage(state.node, open);
if (contact.status === 'connected') {
await card.actions.setCardConnected(added.id, contact.token, contact);
}
});
},
confirmAndConnect: async () => {
await applyAction(async () => {
await card.actions.setCardConfirmed(state.cardId);
await card.actions.setCardConnecting(state.cardId);
let open = await card.actions.getCardOpenMessage(state.cardId);
let contact = await card.actions.setCardOpenMessage(state.node, open);
if (contact.status === 'connected') {
await card.actions.setCardConnected(state.cardId, contact.token, contact);
}
});
},
saveContact: async () => {
await applyAction(async () => {
let message = await getListingMessage(state.node, state.guid);
await card.actions.addCard(message);
});
},
disconnectContact: async () => {
await applyAction(async () => {
await card.actions.setCardConfirmed(state.cardId);
try {
let message = await card.actions.getCardCloseMessage(state.cardId);
await card.actions.setCardCloseMessage(state.node, message);
}
catch (err) {
console.log(err);
}
});
},
confirmContact: async () => {
await applyAction(async () => {
await card.actions.setCardConfirmed(state.cardId);
});
},
ignoreContact: async () => {
await applyAction(async () => {
await card.actions.setCardConfirmed(state.cardId);
});
},
closeDelete: async () => {
await applyAction(async () => {
await card.actions.setCardConfirmed(state.cardId);
try {
let message = await card.actions.getCardCloseMessage(state.cardId);
await card.actions.setCardCloseMessage(state.node, message);
}
catch (err) {
console.log(err);
}
await card.actions.removeCard(state.cardId);
});
},
deleteContact: async () => {
await applyAction(async () => {
await card.actions.removeCard(state.cardId);
});
},
connectContact: async () => {
await applyAction(async () => {
await card.actions.setCardConnecting(state.cardId);
let message = await card.actions.getCardOpenMessage(state.cardId);
let contact = await card.actions.setCardOpenMessage(state.node, message);
if (contact.status === 'connected') {
await card.actions.setCardConnected(state.cardId, contact.token, contact);
}
});
},
blockContact: async () => {
await applyAction(async () => {
await card.actions.setCardBlocked(state.cardId);
});
},
reportContact: async () => {
await addFlag(state.node, state.guid);
},
resync: () => {
card.actions.resync(contact.card);
},
};
return { state, actions };
}

View File

@ -1,7 +1,7 @@
import { Text } from 'react-native';
export function RegistryTitle({ state, actions }) {
return <Text>RegistryTitle</Text>
export function RegistryHeader({ state, actions }) {
return <Text>RegistryHeader</Text>
}
export function RegistryBody({ state, actions, openContact }) {