import React, { useContext, useEffect, useState } from 'react' import { StyleSheet, View } from 'react-native' import { AppContext } from '../../Contexts/AppContext' import { Event } from '../../lib/nostr/Events' import { useTranslation } from 'react-i18next' import { RelayPoolContext } from '../../Contexts/RelayPoolContext' import getUnixTime from 'date-fns/getUnixTime' import { Note } from '../../Functions/DatabaseFunctions/Notes' import { getETags, getTaggedPubKeys } from '../../Functions/RelayFunctions/Events' import { getUsers, User } from '../../Functions/DatabaseFunctions/Users' import { formatPubKey } from '../../Functions/RelayFunctions/Users' import { Button, Switch, Text, TextInput, TouchableRipple } from 'react-native-paper' import { UserContext } from '../../Contexts/UserContext' import { goBack } from '../../lib/Navigation' import { Kind } from 'nostr-tools' import ProfileData from '../../Components/ProfileData' import NoteCard from '../../Components/NoteCard' interface SendPageProps { route: { params: { note: Note; type?: 'reply' | 'repost' } | undefined } } export const SendPage: React.FC = ({ route }) => { const { database } = useContext(AppContext) const { publicKey } = useContext(UserContext) const { relayPool, lastConfirmationtId } = useContext(RelayPoolContext) const { t } = useTranslation('common') // state const [content, setContent] = useState('') const [contentWarning, setContentWarning] = useState(false) const [userSuggestions, setUserSuggestions] = useState([]) const [userMentions, setUserMentions] = useState([]) const [isSending, setIsSending] = useState(false) const note = React.useMemo(() => route.params?.note, []) useEffect(() => { if (isSending) goBack() }, [lastConfirmationtId]) const onChangeText: (text: string) => void = (text) => { const match = text.match(/.*@(.*)$/) const note: Note | undefined = route.params?.note if (database && match && match?.length > 0) { let request = getUsers(database, { name: match[1], order: 'contact DESC,name ASC' }) if (match[1] === '' && note) { const taggedPubKeys = getTaggedPubKeys(note) request = getUsers(database, { includeIds: [...taggedPubKeys, note.pubkey], order: 'contact DESC,name ASC', }) } request.then((results) => { setUserSuggestions(results.filter((item) => item.id !== publicKey)) }) } else { setUserSuggestions([]) } setContent(text) } const mentionText: (user: User) => string = (user) => { return `@${user.name ?? formatPubKey(user.id)}` } const onPressSend: () => void = () => { if (database && publicKey) { setIsSending(true) let tags: string[][] = [] let rawContent = content if (note?.id) { if (route.params?.type === 'reply') { tags = note.tags if (getETags(note).length === 0) { tags.push(['e', note.id, '', 'root']) } else { tags.push(['e', note.id, '', 'reply']) } tags.push(['p', note.pubkey, '']) } else if (route.params?.type === 'repost') { rawContent = `#[${tags.length}] ${rawContent}` tags.push(['e', note.id, '', '']) } } if (contentWarning) tags.push(['content-warning', '']) if (userMentions.length > 0) { userMentions.forEach((user) => { const userText = mentionText(user) if (rawContent.includes(userText)) { rawContent = rawContent.replace(userText, `#[${tags.length}]`) tags.push(['p', user.id]) } }) } const event: Event = { content: rawContent, created_at: getUnixTime(new Date()), kind: Kind.Text, pubkey: publicKey, tags, } relayPool?.sendEvent(event).catch(() => {}) } } const addUserMention: (user: User) => void = (user) => { setUserMentions((prev) => { prev.push(user) return prev }) setContent((prev) => { const splitText = prev.split('@') splitText.pop() return `${splitText.join('@')}${mentionText(user)} ` }) setUserSuggestions([]) } const renderContactItem: (item: User, index: number) => JSX.Element = (item, index) => ( addUserMention(item)}> {item.contact ? t('sendPage.isContact') : t('sendPage.isNotContact')} ) return ( <> {note && ( )} ref?.focus()} mode='outlined' multiline numberOfLines={30} outlineStyle={{ borderColor: 'transparent' }} value={content} onChangeText={onChangeText} scrollEnabled /> {userSuggestions.length > 0 ? ( {userSuggestions.map((user, index) => renderContactItem(user, index))} ) : ( // FIXME: can't find this color {t('sendPage.contentWarning')} )} ) } const styles = StyleSheet.create({ textInputContainer: { flex: 1, }, textInput: { paddingBottom: 0, }, noteCard: { flexDirection: 'column-reverse', paddingLeft: 16, paddingRight: 16, }, actions: { height: 100, flexDirection: 'column-reverse', zIndex: 999, }, contactsList: { bottom: 0, maxHeight: 200, }, contactRow: { paddingLeft: 16, paddingRight: 16, paddingTop: 16, flexDirection: 'row', justifyContent: 'space-between', width: '100%', }, contactData: { paddingLeft: 16, }, contactName: { flexDirection: 'row', }, contactInfo: { flexDirection: 'row', alignContent: 'center', }, contactFollow: { justifyContent: 'center', }, contentWarning: { flexDirection: 'row', alignContent: 'center', justifyContent: 'space-between', paddingLeft: 16, paddingRight: 16, paddingTop: 16, }, send: { padding: 16, }, verifyIcon: { paddingTop: 4, paddingLeft: 5, }, }) export default SendPage