import React, { useContext, useEffect, useState } from 'react' import { Clipboard, Dimensions, FlatList, ListRenderItem, ScrollView, StyleSheet, View, } from 'react-native' import { AppContext } from '../../Contexts/AppContext' import { RelayPoolContext } from '../../Contexts/RelayPoolContext' import { EventKind } from '../../lib/nostr/Events' import { DirectMessage, getGroupedDirectMessages, } from '../../Functions/DatabaseFunctions/DirectMessages' import { getUsers, User } from '../../Functions/DatabaseFunctions/Users' import { getOtherPubKey } from '../../Functions/RelayFunctions/DirectMessages' import { NostrosAvatar } from '../../Components/NostrosAvatar' import { formatPubKey, username } from '../../Functions/RelayFunctions/Users' import { AnimatedFAB, Badge, Button, Divider, List, Text, TextInput, TouchableRipple, useTheme, } from 'react-native-paper' import { UserContext } from '../../Contexts/UserContext' import { navigate } from '../../lib/Navigation' import moment from 'moment' import RBSheet from 'react-native-raw-bottom-sheet' import { useTranslation } from 'react-i18next' import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons' export const ConversationsFeed: React.FC = () => { const theme = useTheme() const { t } = useTranslation('common') const { database } = useContext(AppContext) const { publicKey, privateKey } = useContext(UserContext) const { relayPool, lastEventId } = useContext(RelayPoolContext) const [directMessages, settDirectMessages] = useState([]) const [sendPubKeyInput, setSendPubKeyInput] = useState('') const [users, setUsers] = useState() const bottomSheetCreateRef = React.useRef(null) const bottomSheetUserListRef = React.useRef(null) const bottomSheetPubKeyRef = React.useRef(null) useEffect(() => { loadDirectMessages() }, [lastEventId]) useEffect(() => { loadDirectMessages() subscribeDirectMessages() }, []) const loadDirectMessages: () => void = () => { if (database && publicKey) { getGroupedDirectMessages(database, {}).then((results) => { if (results && results.length > 0) { settDirectMessages(results) const otherUsers = results.map((message) => getOtherPubKey(message, publicKey)) relayPool?.subscribe('directmessages-meta', [ { kinds: [EventKind.meta], authors: otherUsers, }, ]) getUsers(database, { contacts: true }).then(setUsers) } }) } } const subscribeDirectMessages: () => void = async () => { relayPool?.unsubscribeAll() if (publicKey) { relayPool?.subscribe('directmessages-user', [ { kinds: [EventKind.directMessage], authors: [publicKey], }, { kinds: [EventKind.directMessage], '#p': [publicKey], }, ]) } } const renderConversationItem: ListRenderItem = ({ index, item }) => { if (!publicKey || !privateKey) return <> const otherPubKey = getOtherPubKey(item, publicKey) const user: User = users?.find((user) => user.id === otherPubKey) ?? { id: otherPubKey } return ( navigate('Conversation', { pubKey: user.id, conversationId: item.conversation_id }) } > {username(user)} {moment.unix(item.created_at).format('HH:mm DD-MM-YY')} {!item.read && } ) } const pastePubKey: () => void = () => { Clipboard.getString().then((value) => { setSendPubKeyInput(value ?? '') }) } const bottomSheetStyles = React.useMemo(() => { return { container: { backgroundColor: theme.colors.background, padding: 16, borderTopRightRadius: 28, borderTopLeftRadius: 28, }, draggableIcon: { backgroundColor: '#000', }, } }, []) const createOptions = React.useMemo(() => { return [ { key: 1, title: t('conversationsFeed.newMessageContact'), left: () => ( } /> ), onPress: async () => bottomSheetUserListRef.current?.open(), }, { key: 2, title: t('conversationsFeed.addPubKey'), left: () => ( } /> ), onPress: async () => bottomSheetPubKeyRef.current?.open(), }, ] }, []) const renderUserItem: ListRenderItem = ({ index, item }) => ( {}}> {formatPubKey(item.id)} {item.name && {username(item)}} ) return ( bottomSheetCreateRef.current?.open()} animateFrom='right' iconMode='static' extended={false} /> { return ( ) }} ItemSeparatorComponent={Divider} /> {t('conversationsFeed.openMessageTitle')} {t('conversationsFeed.openMessageDescription')} } /> ) } const styles = StyleSheet.create({ container: { flex: 1, }, contactRow: { paddingLeft: 16, paddingRight: 16, paddingTop: 16, flexDirection: 'row', justifyContent: 'space-between', width: '100%', }, contactName: { paddingLeft: 16, }, contactUser: { flexDirection: 'row', alignContent: 'center', }, contactInfo: { alignContent: 'center', justifyContent: 'space-between', }, contactFollow: { justifyContent: 'center', }, fab: { right: 16, position: 'absolute', }, }) export default ConversationsFeed