diff --git a/app/mobile/src/constants/Strings.js b/app/mobile/src/constants/Strings.js index 6914fc53..6ebe5c76 100644 --- a/app/mobile/src/constants/Strings.js +++ b/app/mobile/src/constants/Strings.js @@ -85,7 +85,7 @@ const Strings = [ // contacts page add: 'Add', back: 'Back', - deleteContact: 'Deleting Contact', + deleteContact: 'Delete Contact', confirmDelete: 'Delete', disconnectContact: 'Disconnect from Contact', confirmDisconnect: 'Disconnect', diff --git a/app/mobile/src/session/contact/Contact.jsx b/app/mobile/src/session/contact/Contact.jsx index 636b64be..27f64678 100644 --- a/app/mobile/src/session/contact/Contact.jsx +++ b/app/mobile/src/session/contact/Contact.jsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Alert, View, Text, TouchableOpacity, ScrollView, Image } from 'react-native'; +import { ActivityIndicator, Alert, View, Text, TouchableOpacity, ScrollView, Image } from 'react-native'; import { styles } from './Contact.styled'; import { useContact } from './useContact.hook'; import Ionicons from 'react-native-vector-icons/AntDesign'; @@ -307,10 +307,9 @@ export function ContactBody({ contact }) { export function Contact({ contact, drawer, back }) { const [busy, setBusy] = useState(false); - const { state, actions } = useContact(contact); + const { state, actions } = useContact(contact, back); const OVERLAP = 32; - const promptAction = (prompt, action) => { prompt(async () => { if (!busy) { @@ -322,12 +321,35 @@ export function Contact({ contact, drawer, back }) { catch (err) { console.log(err); setBusy(false); + Alert.alert( + state.strings.error, + state.strings.tryAgain, + ); throw err; } } }); } + const setAction = async (action) => { + if (!busy) { + try { + setBusy(true); + await new Promise(r => setTimeout(r, 100)); + await action(); + setBusy(false); + } + catch (err) { + console.log(err); + setBusy(false); + Alert.alert( + state.strings.error, + state.strings.tryAgain, + ); + } + } + } + return ( <> { drawer && ( @@ -351,7 +373,7 @@ export function Contact({ contact, drawer, back }) { { state.strings.name } )} - { state.username } + { state.username } { state.status === 'offsync' && ( @@ -383,9 +405,9 @@ export function Contact({ contact, drawer, back }) { { state.strings.pending } )} - { state.status === 'saved' && ( - - { state.strings.saved } + { state.status === 'confirmed' && ( + + { state.strings.confirmed } )} { state.status === 'unsaved' && ( @@ -419,74 +441,103 @@ export function Contact({ contact, drawer, back }) { - - { state.status === 'offsync' && ( - - - { state.strings.actionResync } - - )} - { (state.status === 'unsaved' || state.status === 'confirmed') && ( - - - { state.strings.actionConnect } - - )} - { (state.status === 'received' || state.status === 'pending') && ( - - - { state.strings.actionAccept } - - )} - { (state.status === 'received' || state.status === 'pending') && ( - - - { state.strings.actionIgnore } - - )} - { state.status === 'connected' && ( - promptAction(actions.disconnectPrompt, actions.disconnectContact)}> - - { state.strings.actionDisconnect } - - )} - { state.status === 'connecting' && ( - - - { state.strings.actionCancel } - - )} - { (state.status === 'pending' || state.status === 'unsaved') && ( - - - { state.strings.actionSave } - - )} - { (state.status === 'connected' || state.status === 'connecting' || state.status === 'received') && ( - promptAction(actions.deletePrompt, actions.closeDelete)}> - - { state.strings.actionDelete } - - )} - { state.status === 'confirmed' && ( - promptAction(actions.deletePrompt, actions.deleteContact)}> - - { state.strings.actionDelete } - - )} - { state.status !== 'unsaved' && state.status !== 'pending' && ( - promptAction(actions.blockPrompt, actions.blockContact)}> - - { state.strings.actionBlock } - - )} - { true && ( + { busy && ( + + + + )} + { !busy && ( + + { state.status === 'offsync' && ( + + + { state.strings.actionResync } + + )} + { state.status === 'unsaved' && ( + setAction(actions.saveAndConnect)}> + + { state.strings.actionConnect } + + )} + { state.status === 'confirmed' && ( + setAction(actions.connectContact)}> + + { state.strings.actionConnect } + + )} + { state.status === 'received' && ( + setAction(actions.connectContact)}> + + { state.strings.actionAccept } + + )} + { state.status === 'pending' && ( + setAction(actions.confirmAndConnect)}> + + { state.strings.actionAccept } + + )} + { state.status === 'received' && ( + setAction(actions.disconnectContact)}> + + { state.strings.actionIgnore } + + )} + { state.status === 'pending' && ( + setAction(actions.ignoreContact)}> + + { state.strings.actionIgnore } + + )} + { state.status === 'connected' && ( + promptAction(actions.disconnectPrompt, actions.disconnectContact)}> + + { state.strings.actionDisconnect } + + )} + { state.status === 'connecting' && ( + setAction(actions.disconnectContact)}> + + { state.strings.actionCancel } + + )} + { state.status === 'pending' && ( + setAction(actions.confirmContact)}> + + { state.strings.actionSave } + + )} + { state.status === 'unsaved' && ( + setAction(actions.saveContact)}> + + { state.strings.actionSave } + + )} + { (state.status === 'connected' || state.status === 'connecting' || state.status === 'received') && ( + promptAction(actions.deletePrompt, actions.closeDelete)}> + + { state.strings.actionDelete } + + )} + { state.status === 'confirmed' && ( + promptAction(actions.deletePrompt, actions.deleteContact)}> + + { state.strings.actionDelete } + + )} + { state.status !== 'unsaved' && state.status !== 'pending' && ( + promptAction(actions.blockPrompt, actions.blockContact)}> + + { state.strings.actionBlock } + + )} promptAction(actions.reportPrompt, actions.reportContact)}> { state.strings.actionReport } - )} - + + )} diff --git a/app/mobile/src/session/contact/Contact.styled.js b/app/mobile/src/session/contact/Contact.styled.js index b9b7ba79..98018cbe 100644 --- a/app/mobile/src/session/contact/Contact.styled.js +++ b/app/mobile/src/session/contact/Contact.styled.js @@ -17,6 +17,13 @@ export const styles = StyleSheet.create({ logo: { alignSelf: 'center', }, + busy: { + width: '100%', + display: 'flex', + alignItems: 'flex-start', + justifyContent: 'center', + flex: 1, + }, details: { minHeight: 32, borderTopRightRadius: 32, diff --git a/app/mobile/src/session/contact/useContact.hook.js b/app/mobile/src/session/contact/useContact.hook.js index 1c19e8ff..a1458f75 100644 --- a/app/mobile/src/session/contact/useContact.hook.js +++ b/app/mobile/src/session/contact/useContact.hook.js @@ -10,7 +10,7 @@ import { getCardByGuid } from 'context/cardUtil'; import { getLanguageStrings } from 'constants/Strings'; import avatar from 'images/avatar.png'; -export function useContact(contact) { +export function useContact(contact, back) { const [state, setState] = useState({ name: null, @@ -95,66 +95,50 @@ export function useContact(contact) { 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); - } - }); + 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); - } - }); + 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); - }); + 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); - } - }); + 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); - }); + await card.actions.setCardConfirmed(state.cardId); }, ignoreContact: async () => { - await applyAction(async () => { - await card.actions.setCardConfirmed(state.cardId); - }); + await card.actions.removeCard(state.cardId); + back(); }, deletePrompt: (action) => { display.actions.showPrompt({ title: state.strings.deleteContact, centerButtons: true, - ok: { label: state.strings.confirmDelete, action, failed: () => { - Alert.alert( - state.strings.error, - state.strings.tryAgain, - ); - }}, + ok: { label: state.strings.confirmDelete, action, failed: () => {}}, cancel: { label: state.strings.cancel }, }); }, @@ -162,12 +146,7 @@ export function useContact(contact) { display.actions.showPrompt({ title: state.strings.disconnectContact, centerButtons: true, - ok: { label: state.strings.confirmDisconnect, action, failed: () => { - Alert.alert( - state.strings.error, - state.strings.tryAgain, - ); - }}, + ok: { label: state.strings.confirmDisconnect, action, failed: () => {}}, cancel: { label: state.strings.cancel }, }); }, @@ -175,12 +154,7 @@ export function useContact(contact) { display.actions.showPrompt({ title: state.strings.blockContact, centerButtons: true, - ok: { label: state.strings.confirmBlock, action, failed: () => { - Alert.alert( - state.strings.error, - state.strings.tryAgain, - ); - }}, + ok: { label: state.strings.confirmBlock, action, failed: () => {}}, cancel: { label: state.strings.cancel }, }); }, @@ -188,47 +162,37 @@ export function useContact(contact) { display.actions.showPrompt({ title: state.strings.reportContact, centerButtons: true, - ok: { label: state.strings.confirmReport, action, failed: () => { - Alert.alert( - state.strings.error, - state.strings.tryAgain, - ); - }}, + ok: { label: state.strings.confirmReport, action, failed: () => {}}, cancel: { label: state.strings.cancel }, }); }, 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); - }); + 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); + back(); }, deleteContact: async () => { - await applyAction(async () => { - await card.actions.removeCard(state.cardId); - }); + await card.actions.removeCard(state.cardId); + back(); }, 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); - } - }); + 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.setCardFlag(state.cardId); - }); + await card.actions.setCardFlag(state.cardId); + back(); }, reportContact: async () => { await addFlag(state.node, state.guid);