Skip to content

Commit

Permalink
contacts integration
Browse files Browse the repository at this point in the history
  • Loading branch information
akintewe committed Oct 25, 2024
1 parent c209641 commit 2494b20
Show file tree
Hide file tree
Showing 9 changed files with 672 additions and 55 deletions.
46 changes: 46 additions & 0 deletions apps/mobile/src/components/ContactsRow/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {Contact} from 'afk_nostr_sdk';
import React from 'react';
import {Image, ScrollView, Text, TouchableOpacity, View} from 'react-native';

import {useStyles} from '../../hooks';
import stylesheet from './styles';

interface ContactsRowProps {
contacts: Contact[];
onContactPress: (contact: Contact) => void;
onAddContact: () => void;
}

export const ContactsRow: React.FC<ContactsRowProps> = ({
contacts,
onContactPress,
onAddContact,
}) => {
const styles = useStyles(stylesheet);
return (
<View style={styles.contactsContainer}>
<Text style={styles.contactsTitle}>Contacts</Text>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.contactsScrollContent}
>
<TouchableOpacity style={styles.addContactButton} onPress={onAddContact}>
<Text style={styles.plusSign}>+</Text>
</TouchableOpacity>

{contacts.map((contact) => (
<View key={contact.pubkey} style={styles.contactAvatar}>
<Image
source={contact.image ? {uri: contact.image} : require('../../assets/pepe-logo.png')}
style={styles.avatarImage}
/>
<Text style={styles.contactName} numberOfLines={1}>
{contact.displayName || 'Unnamed'}
</Text>
</View>
))}
</ScrollView>
</View>
);
};
50 changes: 50 additions & 0 deletions apps/mobile/src/components/ContactsRow/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {ThemedStyleSheet} from '../../styles';

export default ThemedStyleSheet((theme) => ({
contactsContainer: {
paddingHorizontal: 16,
marginBottom: 16,
},
contactsTitle: {
fontSize: 16,
fontWeight: 'bold',
color: theme.colors.text,
marginBottom: 12,
},
contactsScrollContent: {
flexDirection: 'row',
alignItems: 'center',
},
addContactButton: {
width: 50,
height: 50,
borderRadius: 25,
backgroundColor: theme.colors.primary,
justifyContent: 'center',
alignItems: 'center',
marginRight: 12,
},
plusSign: {
color: theme.colors.white,
fontSize: 24,
fontWeight: 'bold',
lineHeight: 24,
},
contactAvatar: {
alignItems: 'center',
marginRight: 12,
width: 50,
},
avatarImage: {
width: 50,
height: 50,
borderRadius: 25,
marginBottom: 4,
},
contactName: {
fontSize: 12,
color: theme.colors.text,
textAlign: 'center',
width: '100%',
},
}));
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {NDKUser} from '@nostr-dev-kit/ndk';
import {useQueryClient} from '@tanstack/react-query';
import {useSendPrivateMessage} from 'afk_nostr_sdk';
import React from 'react';
import {Contact, getContacts, useSendPrivateMessage} from 'afk_nostr_sdk';
import React, {useEffect, useState} from 'react';
import {View} from 'react-native';

import {useStyles} from '../../../hooks';
import {useToast} from '../../../hooks/modals';
import {ContactsRow} from '../../ContactsRow';
import {Divider} from '../../Divider';
import {IconButton} from '../../IconButton';
import {Input} from '../../Input';
Expand All @@ -18,13 +19,15 @@ interface IFormPrivateMessage {
receiverPublicKeyProps?: string;
handleClose?: () => void;
}

export const FormPrivateMessage: React.FC<IFormPrivateMessage> = ({
user,
publicKey,
handleClose,
receiverPublicKeyProps,
}) => {
const styles = useStyles(stylesheet);
const [storedContacts, setStoredContacts] = useState<Contact[]>([]);
const avatar = user?.profile?.banner ?? require('../../../assets/pepe-logo.png');

const [receiverPublicKey, setReceiverPublicKey] = React.useState(receiverPublicKeyProps);
Expand All @@ -33,15 +36,28 @@ export const FormPrivateMessage: React.FC<IFormPrivateMessage> = ({
const {showToast} = useToast();
const queryClient = useQueryClient();

useEffect(() => {
const fetchContacts = () => {
const contactsData = getContacts();
if (contactsData) {
setStoredContacts(JSON.parse(contactsData));
}
};
fetchContacts();
}, []);

const handleContactSelect = (contact: Contact) => {
if (contact.pubkey) {
setReceiverPublicKey(contact.pubkey);
}
};

const sendMessage = async (message: string) => {
if (!receiverPublicKey) {
showToast({title: 'Please choose a Nostr public key', type: 'error'});
return;
}

//todo: integrate hook here
//todo: encrypt message
//todo: send message
await sendPrivateMessage.mutateAsync(
{receiverPublicKeyProps: receiverPublicKey, content: message},
{
Expand All @@ -59,50 +75,28 @@ export const FormPrivateMessage: React.FC<IFormPrivateMessage> = ({
);
};

const handleSendMessage = () => {
if (!message) {
showToast({title: 'Please add a content', type: 'error'});
return;
}
if (!receiverPublicKey) {
showToast({title: 'Please choose a Nostr public key', type: 'error'});
return;
}

sendMessage(message);
};

return (
<>
{/* <View style={styles.header}>
<IconButton icon="ChevronLeftIcon" size={20} onPress={handleGoBack} style={styles.backButton} />
<View style={styles.headerContent}>
<Image source={avatar} style={styles.avatar} />
<Text style={styles.name}>{user.name}</Text>
</View>
</View> */}
<View style={styles.container}>
<Input
value={receiverPublicKey}
onChangeText={setReceiverPublicKey}
placeholder="Receiver"
/>
<KeyboardFixedView containerProps={{style: styles.commentInputContainer}}>
<Divider />

<View style={styles.commentInputContent}>
<Input
value={message}
onChangeText={setMessage}
containerStyle={styles.commentInput}
placeholder="Type your message"
/>

<IconButton icon="SendIcon" size={20} onPress={handleSendMessage} />
</View>
</KeyboardFixedView>
{/* <MessageInput onSend={handleSendMessage} /> */}
</View>
</>
<View style={styles.container}>
<ContactsRow
contacts={storedContacts}
onContactPress={handleContactSelect}
onAddContact={() => {
// Handle add contact action
showToast({title: 'Add contact functionality to be implemented', type: 'info'});
}}
/>
<KeyboardFixedView containerProps={{style: styles.commentInputContainer}}>
<Divider />
<View style={styles.commentInputContent}>
<Input
value={message}
onChangeText={setMessage}
containerStyle={styles.commentInput}
placeholder="Type your message"
/>
<IconButton icon="SendIcon" size={20} onPress={() => message && sendMessage(message)} />
</View>
</KeyboardFixedView>
</View>
);
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {Spacing, ThemedStyleSheet} from '../../../styles';
export default ThemedStyleSheet((theme) => ({
container: {
flex: 1,
backgroundColor: theme.colors.background,
backgroundColor: theme.colors.surface,
},
header: {
padding: 10,
Expand Down Expand Up @@ -48,4 +48,4 @@ export default ThemedStyleSheet((theme) => ({
flex: 1,
width: 'auto',
},
}));
}));
Loading

0 comments on commit 2494b20

Please sign in to comment.