diff --git a/app/mobile/src/context/cardUtil.js b/app/mobile/src/context/cardUtil.js index a6182258..04c0479e 100644 --- a/app/mobile/src/context/cardUtil.js +++ b/app/mobile/src/context/cardUtil.js @@ -1,7 +1,7 @@ export function getCardByGuid(cards, guid) { let card = null; cards.forEach((value, key, map) => { - if(value?.data?.cardProfile?.guid === guid) { + if(value?.card.profile?.guid === guid) { card = value; } }); @@ -9,12 +9,7 @@ export function getCardByGuid(cards, guid) { } export function getProfileByGuid(cards, guid) { - const card = getCardByGuid(cards, guid); - if (card?.data?.cardProfile) { - const { name, handle, imageSet, node } = card.data.cardProfile; - const cardId = card.id; - return { cardId, name, handle, imageSet, node } - } - return {}; + const { cardId, name, handle, imageSet, node } = getCardByGuid(cards, guid) || {} + return { cardId, name, handle, imageSet, node } } diff --git a/app/mobile/src/session/Session.jsx b/app/mobile/src/session/Session.jsx index b506b199..339b64ac 100644 --- a/app/mobile/src/session/Session.jsx +++ b/app/mobile/src/session/Session.jsx @@ -126,7 +126,7 @@ export function Session() { ( )}}> - {(props) => } + {(props) => } ( @@ -237,8 +237,13 @@ export function Session() { const [contact, setContact] = useState(null); return ( - }> + ( + + + + + + )}> {(props) => } diff --git a/app/mobile/src/session/cards/cardItem/CardItem.jsx b/app/mobile/src/session/cards/cardItem/CardItem.jsx index 20ba4d3c..3d1b2e9f 100644 --- a/app/mobile/src/session/cards/cardItem/CardItem.jsx +++ b/app/mobile/src/session/cards/cardItem/CardItem.jsx @@ -7,7 +7,7 @@ export function CardItem({ item, openContact }) { const select = () => { const { guid, name, handle, node, location, description, imageSet } = item; const contact = { guid, name, handle, node, location, description, imageSet }; - openContact({ contact }); + openContact(contact); }; return ( diff --git a/app/mobile/src/session/contact/Contact.jsx b/app/mobile/src/session/contact/Contact.jsx index 4f1a2497..6670342a 100644 --- a/app/mobile/src/session/contact/Contact.jsx +++ b/app/mobile/src/session/contact/Contact.jsx @@ -1,20 +1,303 @@ -import { Text } from 'react-native'; +import { Alert, View, Text, TouchableOpacity } from 'react-native'; +import { styles } from './Contact.styled'; +import { useContact } from './useContact.hook'; +import Ionicons from 'react-native-vector-icons/AntDesign'; +import { Logo } from 'utils/Logo'; +import { Colors } from 'constants/Colors'; -export function ContactHeader({ contact, closeContact }) { +export function ContactHeader({ contact }) { return ( - ContactTitle - ); + { `${contact?.handle}@${contact?.node}` } + ) } export function ContactBody({ contact }) { + const { state, actions } = useContact(contact); + + const getStatusText = (status) => { + if (status === 'confirmed') { + return 'saved'; + } + if (status === 'pending') { + return 'unknown contact request'; + } + if (status === 'connecting') { + return 'request sent'; + } + if (status === 'connected') { + return 'connected'; + } + if (status === 'requested') { + return 'request received'; + } + return 'unsaved'; + } + + const setContact = async (action) => { + try { + await action(); + } + catch (err) { + console.log(err); + Alert.alert( + 'Failed to Update Contact', + 'Please try again.', + ); + } + } + + const cancelRequest = () => { + Alert.alert( + "Closing Request", + "Confirm?", + [ + { text: "Cancel", + onPress: () => {}, + }, + { text: "Close", onPress: () => { + setContact(actions.disconnectContact); + }} + ] + ); + } + + const disconnectContact = () => { + Alert.alert( + "Disconnecting Contact", + "Confirm?", + [ + { text: "Cancel", + onPress: () => {}, + }, + { text: "Disconnect", onPress: () => { + setContact(actions.disconnectContact); + }} + ] + ); + } + + const saveAndConnect = () => { + setContact(actions.saveAndConnect); + } + + const confirmAndConnect = () => { + setContact(actions.confirmAndConnect); + } + + const saveContact = () => { + setContact(actions.saveContact); + } + + const confirmContact = () => { + setContact(actions.confirmContact); + } + + const ignoreContact = () => { + setContact(actions.ignoreContact); + } + + const deleteContact = () => { + Alert.alert( + "Deleting Contact", + "Confirm?", + [ + { text: "Cancel", + onPress: () => {}, + }, + { text: "Delete", onPress: () => { + setContact(actions.deleteContact); + }} + ] + ); + } + + const closeDelete = () => { + Alert.alert( + "Deleting Contact", + "Confirm?", + [ + { text: "Cancel", + onPress: () => {}, + }, + { text: "Delete", onPress: () => { + setContact(actions.closeDelete); + }} + ] + ); + } + + const blockContact = () => { + Alert.alert( + "Blocking Contact", + "Confirm?", + [ + { text: "Cancel", + onPress: () => {}, + }, + { text: "Block", onPress: () => { + setContact(actions.blockContact); + }} + ] + ); + } + + const reportContact = () => { + Alert.alert( + "Report Contact", + "Confirm?", + [ + { text: "Cancel", + onPress: () => {}, + }, + { text: "Report", onPress: () => { + setContact(actions.reportContact); + }} + ] + ); + } + + const connectContact = () => { + setContact(actions.connectContact); + } + return ( - ContactBody + + { `[${getStatusText(state.status)}]` } + + + + + + { state.name } + + + + + + { state.location } + + + + + + { state.description } + + + + { state.status === 'connected' && ( + <> + + Disconnect + + + Delete Contact + + + Block Contact + + + Report Contact + + + )} + { state.status === 'connecting' && ( + <> + + Close Request + + + Delete Contact + + + Block Contact + + + Report Contact + + + )} + { state.status === 'confirmed' && ( + <> + + Request Connection + + + Delete Contact + + + Block Contact + + + Report Contact + + + )} + { state.status === 'pending' && ( + <> + + Save and Connect + + + Save Contact + + + Ignore Request + + + Block Contact + + + Report Contact + + + )} + { state.status === 'requested' && ( + <> + + Accept Connection + + + Ignore Request + + + Deny Request + + + Delete Contact + + + Block Contact + + + Report Contact + + + )} + { state.status == null && ( + <> + + Save and Connect + + + Save Contact + + + Report Contact + + + )} + + ); } -export function Contact({ contact, closeContact }) { +export function Contact({ contact }) { + return ( - Contact + + + + ); } diff --git a/app/mobile/src/session/contact/Contact.styled.js b/app/mobile/src/session/contact/Contact.styled.js new file mode 100644 index 00000000..c5bf54a8 --- /dev/null +++ b/app/mobile/src/session/contact/Contact.styled.js @@ -0,0 +1,117 @@ +import { StyleSheet } from 'react-native'; +import { Colors } from 'constants/Colors'; + +export const styles = StyleSheet.create({ + container: { + width: '100%', + height: '100%', + display: 'flex', + flexDirection: 'column', + paddingBottom: 32, + alignItems: 'center', + justifyContent: 'center', + backgroundColor: Colors.formBackground, + }, + wrapper: { + backgroundColor: Colors.formBackground, + }, + title: { + fontSize: 18, + }, + resync: { + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + }, + glyph: { + paddingTop: 2, + }, + icon: { + width: 32, + paddingLeft: 8 + }, + drawer: { + paddingTop: 16, + }, + close: { + width: '100%', + display: 'flex', + alignItems: 'flex-end', + paddingRight: 32, + }, + header: { + display: 'flex', + flexDirection: 'row', + alignItems: 'flex-end', + justifyContent: 'center', + }, + status: { + color: Colors.grey, + paddingBottom: 20, + paddingTop: 4, + }, + headerText: { + fontSize: 18, + overflow: 'hidden', + textAlign: 'center', + }, + camera: { + position: 'absolute', + bottom: 0, + left: 0, + padding: 8, + backgroundColor: Colors.lightgrey, + borderBottomLeftRadius: 8, + borderTopRightRadius: 8, + }, + gallery: { + position: 'absolute', + bottom: 0, + right: 0, + padding: 8, + backgroundColor: Colors.lightgrey, + borderBottomRightRadius: 8, + borderTopLeftRadius: 8, + }, + detail: { + paddingTop: 32, + paddingLeft: 32, + paddingRight: 32, + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + color: Colors.text, + }, + attribute: { + display: 'flex', + flexDirection: 'row', + paddingBottom: 8, + }, + nametext: { + fontSize: 18, + paddingRight: 8, + fontWeight: 'bold', + }, + locationtext: { + fontSize: 16, + paddingLeft: 8, + }, + descriptiontext: { + fontSize: 16, + paddingLeft: 8 + }, + button: { + width: 192, + padding: 6, + backgroundColor: Colors.primary, + borderRadius: 4, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + marginTop: 16, + }, + buttonText: { + color: Colors.white, + }, +}) diff --git a/app/mobile/src/session/contact/useContact.hook.js b/app/mobile/src/session/contact/useContact.hook.js index b6caa916..92af0fe7 100644 --- a/app/mobile/src/session/contact/useContact.hook.js +++ b/app/mobile/src/session/contact/useContact.hook.js @@ -3,7 +3,7 @@ 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'; +import { getCardByGuid } from 'context/cardUtil'; export function useContact(contact) { @@ -28,15 +28,15 @@ export function useContact(contact) { } useEffect(() => { - const contactCard = getCardByGuid(contact.guid); + const contactCard = getCardByGuid(card.state.cards, contact?.guid); if (contactCard) { - const { offsync, profile, detail, cardId } = selected.card; + const { offsync, profile, detail, cardId } = contactCard.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 { 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 }); } diff --git a/app/mobile/src/session/profile/Profile.jsx b/app/mobile/src/session/profile/Profile.jsx index 3d01c28c..472ed3c6 100644 --- a/app/mobile/src/session/profile/Profile.jsx +++ b/app/mobile/src/session/profile/Profile.jsx @@ -201,13 +201,13 @@ export function ProfileBody() { - + Change Login { state.sealable && ( - + Sealed Topics )} diff --git a/app/mobile/src/session/registry/registryItem/RegistryItem.jsx b/app/mobile/src/session/registry/registryItem/RegistryItem.jsx index 0fc026ba..77a58489 100644 --- a/app/mobile/src/session/registry/registryItem/RegistryItem.jsx +++ b/app/mobile/src/session/registry/registryItem/RegistryItem.jsx @@ -10,7 +10,7 @@ export function RegistryItem({ item, openContact }) { const select = () => { const { guid, name, handle, node, location, description, imageSet } = item; const contact = { guid, name, handle, node, location, description, imageSet }; - openContact({ contact }); + openContact(contact); } return (