mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 12:39:17 +00:00
rendering contact actions
This commit is contained in:
parent
7eb88452d1
commit
49c2aafaf4
@ -94,15 +94,16 @@ const Strings = [
|
|||||||
unsaved: 'Unsaved',
|
unsaved: 'Unsaved',
|
||||||
offsync: 'Offsync',
|
offsync: 'Offsync',
|
||||||
|
|
||||||
resyncContact: 'Resync',
|
actionResync: 'Resync',
|
||||||
requestConnection: 'Request',
|
actionConnect: 'Connect',
|
||||||
acceptConnection: 'Accept',
|
actionAccept: 'Accept',
|
||||||
saveContact: 'Save',
|
actionSave: 'Save',
|
||||||
cancelRequest: 'Cancel',
|
actionCancel: 'Cancel',
|
||||||
ignoreContact: 'Ignore',
|
actionDisconnect: 'Disconnect',
|
||||||
deleteContact: 'Delete',
|
actionIgnore: 'Ignore',
|
||||||
blockContact: 'Block',
|
actionDelete: 'Delete',
|
||||||
reportContact: 'Report',
|
actionBlock: 'Block',
|
||||||
|
actionReport: 'Report',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
visibleRegistry: 'Visible dans le Registre',
|
visibleRegistry: 'Visible dans le Registre',
|
||||||
@ -194,15 +195,16 @@ const Strings = [
|
|||||||
unsaved: 'Non Enregistré',
|
unsaved: 'Non Enregistré',
|
||||||
offsync: 'Hors Sync',
|
offsync: 'Hors Sync',
|
||||||
|
|
||||||
resyncContact: 'Resync',
|
actionResync: 'Resync',
|
||||||
requestConnection: 'Connexion',
|
actionConnect: 'Connexion',
|
||||||
acceptConnection: 'Accepter',
|
actionAccept: 'Accepter',
|
||||||
saveContact: 'Enregistrer',
|
actionSave: 'Enregistrer',
|
||||||
cancelRequest: 'Annuler',
|
actionCancel: 'Annuler',
|
||||||
ignoreContact: 'Ignorer',
|
actionDisconnect: 'Déconnecter',
|
||||||
deleteContact: 'Supprimer',
|
actionIgnore: 'Ignorer',
|
||||||
blockContact: 'Bloquer',
|
actionDelete: 'Supprimer',
|
||||||
reportContact: 'Signaler',
|
actionBlock: 'Bloquer',
|
||||||
|
actionReport: 'Signaler',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
visibleRegistry: 'Visible en el Registro',
|
visibleRegistry: 'Visible en el Registro',
|
||||||
@ -294,15 +296,16 @@ const Strings = [
|
|||||||
unsaved: 'No Guardado',
|
unsaved: 'No Guardado',
|
||||||
offsync: 'Fuera de Sync',
|
offsync: 'Fuera de Sync',
|
||||||
|
|
||||||
resyncContact: 'Resinc',
|
actionResync: 'Resinc',
|
||||||
requestConnection: 'Conectar',
|
actionConnect: 'Conectar',
|
||||||
acceptConnection: 'Aceptar',
|
actionAccept: 'Aceptar',
|
||||||
saveContact: 'Guardar',
|
actionSave: 'Guardar',
|
||||||
cancelRequest: 'Cancelar',
|
actionCancel: 'Cancelar',
|
||||||
ignoreContact: 'Ignorar',
|
actionDisconnect: 'Desconectar',
|
||||||
deleteContact: 'Borrar',
|
actionIgnore: 'Ignorar',
|
||||||
blockContact: 'Bloquear',
|
actionDelete: 'Borrar',
|
||||||
reportContact: 'Informe',
|
actionBlock: 'Bloquear',
|
||||||
|
actionReport: 'Informe',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
visibleRegistry: 'Sichtbar in der Registrierung',
|
visibleRegistry: 'Sichtbar in der Registrierung',
|
||||||
@ -394,15 +397,16 @@ const Strings = [
|
|||||||
unsaved: 'Nicht Gespeichert',
|
unsaved: 'Nicht Gespeichert',
|
||||||
offsync: 'Nicht Sync',
|
offsync: 'Nicht Sync',
|
||||||
|
|
||||||
resyncContact: 'Neu Sync',
|
actionResync: 'Neu Sync',
|
||||||
requestConnection: 'Verbinden',
|
actionConnect: 'Verbinden',
|
||||||
acceptConnection: 'Akzeptieren',
|
actionAccept: 'Akzeptieren',
|
||||||
saveContact: 'Speichern',
|
actionSave: 'Speichern',
|
||||||
cancelRequest: 'Stornieren',
|
actionCancel: 'Stornieren',
|
||||||
ignoreContact: 'Ignorieren',
|
actionDisconnect: 'Trennen',
|
||||||
deleteContact: 'Löschen',
|
actionIgnore: 'Ignorieren',
|
||||||
blockContact: 'Verstecken',
|
actionDelete: 'Löschen',
|
||||||
reportContact: 'Bericht',
|
actionBlock: 'Verstecken',
|
||||||
|
actionReport: 'Bericht',
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
import { Alert, View, Text, TouchableOpacity, ScrollView, Image } from 'react-native';
|
import { Alert, View, Text, TouchableOpacity, ScrollView, Image } from 'react-native';
|
||||||
import { styles } from './Contact.styled';
|
import { styles } from './Contact.styled';
|
||||||
import { useContact } from './useContact.hook';
|
import { useContact } from './useContact.hook';
|
||||||
@ -5,7 +6,10 @@ import Ionicons from 'react-native-vector-icons/AntDesign';
|
|||||||
import { Logo } from 'utils/Logo';
|
import { Logo } from 'utils/Logo';
|
||||||
import { Colors } from 'constants/Colors';
|
import { Colors } from 'constants/Colors';
|
||||||
import AntIcons from 'react-native-vector-icons/AntDesign';
|
import AntIcons from 'react-native-vector-icons/AntDesign';
|
||||||
import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
import IonIcons from 'react-native-vector-icons/Ionicons';
|
||||||
|
import FntIcons from 'react-native-vector-icons/FontAwesome5';
|
||||||
|
import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
|
import MtrIcons from 'react-native-vector-icons/MaterialIcons';
|
||||||
|
|
||||||
export function ContactHeader({ contact }) {
|
export function ContactHeader({ contact }) {
|
||||||
const handle = contact?.node ? `${contact?.handle}@${contact?.node}` : contact?.handle;
|
const handle = contact?.node ? `${contact?.handle}@${contact?.node}` : contact?.handle;
|
||||||
@ -302,9 +306,45 @@ export function ContactBody({ contact }) {
|
|||||||
|
|
||||||
export function Contact({ contact, drawer, back }) {
|
export function Contact({ contact, drawer, back }) {
|
||||||
|
|
||||||
|
const [busy, setBusy] = useState(false);
|
||||||
const { state, actions } = useContact(contact);
|
const { state, actions } = useContact(contact);
|
||||||
const OVERLAP = 32;
|
const OVERLAP = 32;
|
||||||
|
|
||||||
|
|
||||||
|
const promptDelete = (action) => {
|
||||||
|
actions.deletePrompt(async () => {
|
||||||
|
if (!busy) {
|
||||||
|
try {
|
||||||
|
setBusy(true);
|
||||||
|
await action();
|
||||||
|
setBusy(false);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
setBusy(false);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = async (method) => {
|
||||||
|
if (!busy) {
|
||||||
|
try {
|
||||||
|
setBusy(true);
|
||||||
|
await method();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
Alert.alert(
|
||||||
|
state.strings.error,
|
||||||
|
state.strings.tryAgain,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setBusy(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{ drawer && (
|
{ drawer && (
|
||||||
@ -330,6 +370,11 @@ export function Contact({ contact, drawer, back }) {
|
|||||||
<View style={styles.usernameStatus}>
|
<View style={styles.usernameStatus}>
|
||||||
<Text style={styles.username} numberOfLines={1}>{ state.username }</Text>
|
<Text style={styles.username} numberOfLines={1}>{ state.username }</Text>
|
||||||
<View style={styles.status}>
|
<View style={styles.status}>
|
||||||
|
{ state.status === 'offsync' && (
|
||||||
|
<View style={styles.statusOffsync}>
|
||||||
|
<Text numberOfLines={1} style={styles.statusLabel}>{ state.strings.offsync }</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
{ state.status === 'connected' && (
|
{ state.status === 'connected' && (
|
||||||
<View style={styles.statusConnected}>
|
<View style={styles.statusConnected}>
|
||||||
<Text numberOfLines={1} style={styles.statusLabel}>{ state.strings.connected }</Text>
|
<Text numberOfLines={1} style={styles.statusLabel}>{ state.strings.connected }</Text>
|
||||||
@ -345,11 +390,6 @@ export function Contact({ contact, drawer, back }) {
|
|||||||
<Text numberOfLines={1} style={styles.statusLabel}>{ state.strings.requested }</Text>
|
<Text numberOfLines={1} style={styles.statusLabel}>{ state.strings.requested }</Text>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
{ state.status === 'offsync' && (
|
|
||||||
<View style={styles.statusOffsync}>
|
|
||||||
<Text numberOfLines={1} style={styles.statusLabel}>{ state.strings.offsync }</Text>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
{ state.status === 'received' && (
|
{ state.status === 'received' && (
|
||||||
<View style={styles.statusReceived}>
|
<View style={styles.statusReceived}>
|
||||||
<Text numberOfLines={1} style={styles.statusLabel}>{ state.strings.received }</Text>
|
<Text numberOfLines={1} style={styles.statusLabel}>{ state.strings.received }</Text>
|
||||||
@ -395,6 +435,76 @@ export function Contact({ contact, drawer, back }) {
|
|||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</View>
|
</View>
|
||||||
|
<View style={styles.actions}>
|
||||||
|
<ScrollView horizontal={true} contentContainerStyle={styles.actionList}>
|
||||||
|
{ state.status === 'offsync' && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1}>
|
||||||
|
<MatIcons name="sync" style={styles.actionIcon} size={44} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionResync }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ (state.status === 'unsaved' || state.status === 'confirmed') && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1}>
|
||||||
|
<FntIcons name="people-arrows" style={{ ...styles.actionIcon, paddingBottom: 8 }} size={32} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionConnect }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ (state.status === 'received' || state.status === 'pending') && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1}>
|
||||||
|
<MatIcons name="account-check-outline" style={{ ...styles.actionIcon, paddingBottom: 2 }} size={42} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionAccept }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ (state.status === 'received' || state.status === 'pending') && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1}>
|
||||||
|
<MatIcons name="account-remove-outline" style={{ ...styles.actionIcon, paddingBottom: 2 }} size={42} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionIgnore }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ state.status === 'connected' && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1}>
|
||||||
|
<MatIcons name="account-cancel-outline" style={{ ...styles.actionIcon, paddingBottom: 4 }} size={42} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionDisconnect }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ state.status === 'connecting' && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1}>
|
||||||
|
<MtrIcons name="cancel-schedule-send" style={{ ...styles.actionIcon, paddingBottom: 4 }} size={40} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionCancel }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ (state.status === 'pending' || state.status === 'unsaved') && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1}>
|
||||||
|
<IonIcons name="save-outline" style={{ ...styles.actionIcon, paddingBottom: 4 }} size={38} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionSave }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ (state.status === 'connected' || state.status === 'connecting' || state.status === 'received') && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1} onPress={() => promptDelete(actions.closeDelete)}>
|
||||||
|
<MatIcons name="trash-can-outline" style={{ ...styles.actionIcon, paddingBottom: 4 }} size={40} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionDelete }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ state.status === 'confirmed' && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1} onPress={() => promptDelete(actions.deleteContact)}>
|
||||||
|
<MatIcons name="trash-can-outline" style={{ ...styles.actionIcon, paddingBottom: 4 }} size={40} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionDelete }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ state.status !== 'unsaved' && state.status !== 'pending' && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1}>
|
||||||
|
<MatIcons name="block-helper" style={{ ...styles.actionIcon, paddingBottom: 4 }} size={34} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionBlock }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ true && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1}>
|
||||||
|
<MatIcons name="account-alert-outline" style={{ ...styles.actionIcon, paddingBottom: 4 }} size={40} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionReport }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
@ -163,6 +163,31 @@ export const styles = StyleSheet.create({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexShrink: 1,
|
flexShrink: 1,
|
||||||
},
|
},
|
||||||
|
actions: {
|
||||||
|
marginLeft: 16,
|
||||||
|
marginRight: 16,
|
||||||
|
paddingLeft: 16,
|
||||||
|
paddingRight: 16,
|
||||||
|
backgroundColor: Colors.areaBase,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginTop: 24,
|
||||||
|
height: 80,
|
||||||
|
},
|
||||||
|
actionList: {
|
||||||
|
alignItems: 'flex-end',
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingRight: 24,
|
||||||
|
paddingBottom: 12,
|
||||||
|
},
|
||||||
|
actionIcon: {
|
||||||
|
},
|
||||||
|
actionLabel: {
|
||||||
|
color: Colors.linkText,
|
||||||
|
fontSize: 10,
|
||||||
|
},
|
||||||
divider: {
|
divider: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: 2,
|
height: 2,
|
||||||
|
@ -2,6 +2,7 @@ import { useState, useEffect, useRef, useContext } from 'react';
|
|||||||
import { useWindowDimensions } from 'react-native';
|
import { useWindowDimensions } from 'react-native';
|
||||||
import { CardContext } from 'context/CardContext';
|
import { CardContext } from 'context/CardContext';
|
||||||
import { ProfileContext } from 'context/ProfileContext';
|
import { ProfileContext } from 'context/ProfileContext';
|
||||||
|
import { DisplayContext } from 'context/DisplayContext';
|
||||||
import { getListingMessage } from 'api/getListingMessage';
|
import { getListingMessage } from 'api/getListingMessage';
|
||||||
import { getListingImageUrl } from 'api/getListingImageUrl';
|
import { getListingImageUrl } from 'api/getListingImageUrl';
|
||||||
import { addFlag } from 'api/addFlag';
|
import { addFlag } from 'api/addFlag';
|
||||||
@ -35,6 +36,7 @@ export function useContact(contact) {
|
|||||||
const dimensions = useWindowDimensions();
|
const dimensions = useWindowDimensions();
|
||||||
const card = useContext(CardContext);
|
const card = useContext(CardContext);
|
||||||
const profile = useContext(ProfileContext);
|
const profile = useContext(ProfileContext);
|
||||||
|
const display = useContext(DisplayContext);
|
||||||
|
|
||||||
const updateState = (value) => {
|
const updateState = (value) => {
|
||||||
setState((s) => ({ ...s, ...value }));
|
setState((s) => ({ ...s, ...value }));
|
||||||
@ -143,6 +145,19 @@ export function useContact(contact) {
|
|||||||
await card.actions.setCardConfirmed(state.cardId);
|
await card.actions.setCardConfirmed(state.cardId);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
deletePrompt: (action) => {
|
||||||
|
display.actions.showPrompt({
|
||||||
|
title: state.strings.loggingOut,
|
||||||
|
centerButtons: true,
|
||||||
|
ok: { label: state.strings.confirmLogout, action, failed: () => {
|
||||||
|
Alert.alert(
|
||||||
|
state.strings.error,
|
||||||
|
state.strings.tryAgain,
|
||||||
|
);
|
||||||
|
}},
|
||||||
|
cancel: { label: state.strings.cancel },
|
||||||
|
});
|
||||||
|
},
|
||||||
closeDelete: async () => {
|
closeDelete: async () => {
|
||||||
await applyAction(async () => {
|
await applyAction(async () => {
|
||||||
await card.actions.setCardConfirmed(state.cardId);
|
await card.actions.setCardConfirmed(state.cardId);
|
||||||
|
Loading…
Reference in New Issue
Block a user