diff --git a/frontend/Components/LnPayment/index.tsx b/frontend/Components/LnPayment/index.tsx index 8a6dc40..c4ccdf1 100644 --- a/frontend/Components/LnPayment/index.tsx +++ b/frontend/Components/LnPayment/index.tsx @@ -1,23 +1,22 @@ import React, { useEffect, useState } from 'react' import { requestInvoice } from 'lnurl-pay' -import QRCode from 'react-native-qrcode-svg' import { Event } from '../../lib/nostr/Events' import { User } from '../../Functions/DatabaseFunctions/Users' -import { Linking, StyleSheet, View } from 'react-native' -import Clipboard from '@react-native-clipboard/clipboard' +import { StyleSheet, View } from 'react-native' import { useTranslation } from 'react-i18next' import RBSheet from 'react-native-raw-bottom-sheet' -import { Button, Card, IconButton, Text, TextInput, useTheme } from 'react-native-paper' +import { Button, Text, TextInput, useTheme } from 'react-native-paper' import { AppContext } from '../../Contexts/AppContext' +import LnPreview from '../LnPreview' -interface TextContentProps { +interface LnPaymentProps { open: boolean setOpen: (open: boolean) => void event?: Event user?: User } -export const LnPayment: React.FC = ({ open, setOpen, event, user }) => { +export const LnPayment: React.FC = ({ open, setOpen, event, user }) => { const theme = useTheme() const { t } = useTranslation('common') const { getSatoshiSymbol } = React.useContext(AppContext) @@ -43,14 +42,6 @@ export const LnPayment: React.FC = ({ open, setOpen, event, us setComment(defaultComment) }, [event, open]) - const copyInvoice: () => void = () => { - Clipboard.setString(invoice ?? '') - } - - const openApp: () => void = () => { - Linking.openURL(`lightning:${invoice}`) - } - const generateInvoice: () => void = async () => { if (user?.lnurl && monto !== '') { setLoading(true) @@ -85,21 +76,6 @@ export const LnPayment: React.FC = ({ open, setOpen, event, us } }, []) - const rbSheetQrCustomStyles = React.useMemo(() => { - return { - container: { - backgroundColor: theme.colors.background, - paddingTop: 16, - paddingRight: 16, - paddingBottom: 32, - paddingLeft: 16, - borderTopRightRadius: 28, - borderTopLeftRadius: 28, - height: 'auto', - }, - } - }, []) - return user?.lnurl ? ( <> = ({ open, setOpen, event, us - setOpen(false)} - > - - - - - - - {monto} - {getSatoshiSymbol(23)} - - {comment && ( - - {comment} - - )} - - - - - - {t('lnPayment.copy')} - - - - {t('lnPayment.open')} - - - + {invoice && } ) : ( <> diff --git a/frontend/Components/LnPreview/index.tsx b/frontend/Components/LnPreview/index.tsx new file mode 100644 index 0000000..c5aa89d --- /dev/null +++ b/frontend/Components/LnPreview/index.tsx @@ -0,0 +1,130 @@ +import React, { useEffect, useState } from 'react' +import QRCode from 'react-native-qrcode-svg' +import { Linking, StyleSheet, View } from 'react-native' +import Clipboard from '@react-native-clipboard/clipboard' +import { useTranslation } from 'react-i18next' +import RBSheet from 'react-native-raw-bottom-sheet' +import { Card, IconButton, Text, useTheme } from 'react-native-paper' +import { AppContext } from '../../Contexts/AppContext' +import { decode, PaymentRequestObject, TagsObject } from 'bolt11' + +interface LnPreviewProps { + invoice: string + setInvoice: (invoice: string | undefined) => void +} + +export const LnPreview: React.FC = ({ invoice, setInvoice }) => { + const theme = useTheme() + const { t } = useTranslation('common') + const { getSatoshiSymbol } = React.useContext(AppContext) + const bottomSheetInvoiceRef = React.useRef(null) + const [decodedLnUrl, setDecodedLnUrl] = useState< + PaymentRequestObject & { tagsObject: TagsObject } + >() + + useEffect(() => { + bottomSheetInvoiceRef.current?.open() + setDecodedLnUrl(decode(invoice)) + }, []) + + const copyInvoice: () => void = () => { + Clipboard.setString(invoice ?? '') + } + + const openApp: () => void = () => { + Linking.openURL(`lightning:${invoice}`) + } + + const rbSheetQrCustomStyles = React.useMemo(() => { + return { + container: { + backgroundColor: theme.colors.background, + paddingTop: 16, + paddingRight: 16, + paddingBottom: 32, + paddingLeft: 16, + borderTopRightRadius: 28, + borderTopLeftRadius: 28, + height: 'auto', + }, + } + }, []) + + return ( + <> + setInvoice(undefined)} + > + + + + + + + {decodedLnUrl?.satoshis} + {getSatoshiSymbol(23)} + + + + + + + {t('lnPayment.copy')} + + + + {t('lnPayment.open')} + + + + + ) +} + +const styles = StyleSheet.create({ + drawerBottom: { + justifyContent: 'space-between', + }, + spacer: { + marginBottom: 16, + }, + qrContainer: { + justifyContent: 'center', + alignItems: 'center', + }, + qrText: { + marginTop: 20, + flexDirection: 'row', + justifyContent: 'center', + }, + satoshi: { + fontFamily: 'Satoshi-Symbol', + fontSize: 20, + }, + montoSelection: { + flexDirection: 'row', + }, + montoButton: { + flex: 2, + }, + actionButton: { + justifyContent: 'center', + alignItems: 'center', + width: 80, + }, + cardActions: { + flexDirection: 'row', + justifyContent: 'space-around', + }, + qr: { + justifyContent: 'center', + alignItems: 'center', + padding: 16, + }, +}) + +export default LnPreview diff --git a/frontend/Components/TextContent/index.tsx b/frontend/Components/TextContent/index.tsx index 9d6a21c..73551ba 100644 --- a/frontend/Components/TextContent/index.tsx +++ b/frontend/Components/TextContent/index.tsx @@ -6,12 +6,15 @@ import { AppContext } from '../../Contexts/AppContext' import { getUser, User } from '../../Functions/DatabaseFunctions/Users' import { formatPubKey } from '../../Functions/RelayFunctions/Users' import getUnixTime from 'date-fns/getUnixTime' -import { Card, Text, useTheme } from 'react-native-paper' +import { Avatar, Card, Text, useTheme } from 'react-native-paper' import { getNip19Key, getNpub } from '../../lib/nostr/Nip19' import { navigate } from '../../lib/Navigation' import { validBlueBirdUrl, validImageUrl, validMediaUrl } from '../../Functions/NativeFunctions' import Clipboard from '@react-native-clipboard/clipboard' import FastImage from 'react-native-fast-image' +import { useTranslation } from 'react-i18next' +import { decode, PaymentRequestObject, TagsObject } from 'bolt11' +import LnPreview from '../LnPreview' interface TextContentProps { event?: Event @@ -29,10 +32,16 @@ export const TextContent: React.FC = ({ numberOfLines, }) => { const theme = useTheme() - const { database } = useContext(AppContext) + const { t } = useTranslation('common') + const { database, getSatoshiSymbol } = useContext(AppContext) const [userNames, setUserNames] = useState>({}) const [loadedUsers, setLoadedUsers] = useState(0) const [url, setUrl] = useState() + const [lnUrl, setLnUrl] = useState() + const [invoice, setInvoice] = useState() + const [decodedLnUrl, setDecodedLnUrl] = useState< + PaymentRequestObject & { tagsObject: TagsObject } + >() const [linkPreview, setLinkPreview] = useState() const [linkType, setLinkType] = useState() const text = event?.content ?? content ?? '' @@ -61,6 +70,10 @@ export const TextContent: React.FC = ({ Linking.openURL(url) } + const handleLnUrlPress: () => void = () => { + setInvoice(lnUrl) + } + const handleNip05NotePress: (nip19: string) => void = (nip19) => { const noteId = getNip19Key(nip19) @@ -86,6 +99,14 @@ export const TextContent: React.FC = ({ onPressUser({ id: userPubKey, name: text }) } + const renderLnurl: (lnurl: string | undefined) => string = (lnurl) => { + if (!lnUrl && lnurl) { + setDecodedLnUrl(decode(lnurl)) + setLnUrl(lnurl) + } + return '' + } + const renderMentionText: (matchingString: string, matches: string[]) => string = ( matchingString, matches, @@ -131,9 +152,9 @@ export const TextContent: React.FC = ({ } const generatePreview: () => JSX.Element = () => { - if (!showPreview || !url) return <> + if (!showPreview) return <> - const getRequireCover: () => string = () => { + const getRequireCover: () => string | undefined = () => { if (linkType === 'image') return url return '' @@ -150,34 +171,61 @@ export const TextContent: React.FC = ({ } return ( - - handleUrlPress(url)}> - - - - {/* {linkPreview?.title ?? linkPreview?.url ?? url} */} - {url} - - {/* {linkPreview?.description && ( + + {decodedLnUrl && ( + + + {decodedLnUrl.satoshis} + {getSatoshiSymbol(16)} + + } + left={(props) => ( + + )} + /> + + )} + {url && ( + + handleUrlPress(url)}> + + + + {/* {linkPreview?.title ?? linkPreview?.url ?? url} */} + {url} + + {/* {linkPreview?.description && ( {linkPreview.description} )} */} - - + + + + )} + {invoice && } ) } @@ -185,7 +233,7 @@ export const TextContent: React.FC = ({ return ( = ({ pattern: /#\[(\d+)\]/, }, { pattern: /#(\w+)/, style: styles.hashTag }, + { pattern: /(lnbc)\S*/, style: styles.nip19, renderText: renderLnurl }, { pattern: /(nevent1)\S*/, style: styles.nip19, onPress: handleNip05NotePress }, { pattern: /(npub1|nprofile1)\S*/, diff --git a/frontend/Functions/DatabaseFunctions/DirectMessages/index.ts b/frontend/Functions/DatabaseFunctions/DirectMessages/index.ts index 949319a..b5177c6 100644 --- a/frontend/Functions/DatabaseFunctions/DirectMessages/index.ts +++ b/frontend/Functions/DatabaseFunctions/DirectMessages/index.ts @@ -30,7 +30,7 @@ export const updateAllRead: (db: QuickSQLiteConnection) => Promise Promise = async (db, pubKey) => { const repliesQuery = ` SELECT diff --git a/frontend/Locales/de.json b/frontend/Locales/de.json index 0339d6f..044936b 100644 --- a/frontend/Locales/de.json +++ b/frontend/Locales/de.json @@ -80,7 +80,8 @@ "userBlocked": "Benutzer blockiert", "contentWarning": "Sensibler Inhalt", "recommendation": "Relay Empfehlung", - "addRelay": "Relay hinzufügen" + "addRelay": "Relay hinzufügen", + "reposted": "Reposted" }, "lnPayment": { "monto": "Betrag (sats.)", @@ -195,6 +196,9 @@ "alreadyExists": "Relay already exists." } }, + "textContent": { + "invoice": "Lightning Network invoice" + }, "profileConfigPage": { "notifications": { "nsecCopied": "Privater Schlüssel kopiert.", diff --git a/frontend/Locales/en.json b/frontend/Locales/en.json index 3c85a67..2cd6377 100644 --- a/frontend/Locales/en.json +++ b/frontend/Locales/en.json @@ -80,7 +80,8 @@ "seeParent": "See note", "contentWarning": "Sensitive content", "recommendation": "Relay recomendation", - "addRelay": "Add relay" + "addRelay": "Add relay", + "reposted": "Reposted" }, "lnPayment": { "monto": "Amount (sats)", @@ -245,6 +246,9 @@ "name": "Name", "about": "Description" }, + "textContent": { + "invoice": "Lightning Network invoice" + }, "profilePage": { "notifications": { "contactAdded": "Profile followed", diff --git a/frontend/Locales/es.json b/frontend/Locales/es.json index 81126f7..5ccd4be 100644 --- a/frontend/Locales/es.json +++ b/frontend/Locales/es.json @@ -80,7 +80,8 @@ "userBlocked": "Usuario bloqueado", "contentWarning": "Contenido sensible", "recommendation": "Recomendación de relay", - "addRelay": "Agregar relay" + "addRelay": "Agregar relay", + "reposted": "Reposteado" }, "lnPayment": { "monto": "Cantidad (sats.)", @@ -263,6 +264,9 @@ "copyNip05": "Copiar NIP-05", "copyNPub": "Copiar clave" }, + "textContent": { + "invoice": "Factura de Lightning Network" + }, "profileCard": { "notifications": { "contactAdded": "Siguiendo", diff --git a/frontend/Locales/fr.json b/frontend/Locales/fr.json index bb8f680..4296105 100644 --- a/frontend/Locales/fr.json +++ b/frontend/Locales/fr.json @@ -79,7 +79,8 @@ "reposting": "Republié {{pubkey}}", "seeParent": "Voir la note", "userBlocked": "Utilisateur bloqué", - "contentWarning": "Contenu sensible" + "contentWarning": "Contenu sensible", + "reposted": "Reposted" }, "lnPayment": { "monto": "Quantité (sats.)", @@ -250,6 +251,9 @@ "copyNip05": "Copiar NIP-05", "copyNPub": "Copier la clé" }, + "textContent": { + "invoice": "Lightning Network invoice" + }, "profileCard": { "notifications": { "contactAdded": "Abonné", diff --git a/frontend/Locales/ru.json b/frontend/Locales/ru.json index 97454c0..a190861 100644 --- a/frontend/Locales/ru.json +++ b/frontend/Locales/ru.json @@ -80,7 +80,8 @@ "userBlocked": "Пользователь заблокирован", "contentWarning": "Деликатный контент", "recommendation": "Рекомендованные реле", - "addRelay": "Agregar relay" + "addRelay": "Agregar relay", + "reposted": "Reposted" }, "lnPayment": { "monto": "Cantity (sats.)", @@ -254,6 +255,9 @@ "ru": "Русский", "de": "Deutsch" }, + "textContent": { + "invoice": "Lightning Network invoice" + }, "profileShare": { "notifications": { "npubCopied": "Public key copied.", diff --git a/frontend/Pages/FeedNavigator/index.tsx b/frontend/Pages/FeedNavigator/index.tsx index bd481d5..2a3e9bf 100644 --- a/frontend/Pages/FeedNavigator/index.tsx +++ b/frontend/Pages/FeedNavigator/index.tsx @@ -127,12 +127,8 @@ export const HomeNavigator: React.FC = () => { onPress={() => onPressQuestion(route.name)} /> )} - {historyKey?.includes('messages-') && ( - onPressCheckAll(route.name)} - /> + {['Landing'].includes(route.name) && historyKey?.includes('messages-') && ( + onPressCheckAll()} /> )} ) diff --git a/frontend/Pages/GlobalFeed/index.tsx b/frontend/Pages/GlobalFeed/index.tsx index dfb832e..2873590 100644 --- a/frontend/Pages/GlobalFeed/index.tsx +++ b/frontend/Pages/GlobalFeed/index.tsx @@ -96,21 +96,20 @@ export const GlobalFeed: React.FC = ({ navigation }) => { setRefreshing(false) if (results.length > 0) { setNotes(results) - relayPool?.subscribe('homepage-global-meta', [ + const repostIds = notes.filter((note) => note.repost_id).map((note) => note.id ?? '') + const message: RelayFilters[] = [ { kinds: [Kind.Metadata], authors: results.map((note) => note.pubkey ?? ''), }, - ]) - const repostIds = notes.filter((note) => note.repost_id).map((note) => note.id ?? '') + ] if (repostIds.length > 0) { - relayPool?.subscribe('homepage-global-reposts', [ - { - kinds: [Kind.Text], - '#e': repostIds, - }, - ]) + message.push({ + kinds: [Kind.Text], + '#e': repostIds, + }) } + relayPool?.subscribe('homepage-global-meta', message) } }) } diff --git a/frontend/Pages/HomePage/index.tsx b/frontend/Pages/HomePage/index.tsx index 1efd60c..df7acc7 100644 --- a/frontend/Pages/HomePage/index.tsx +++ b/frontend/Pages/HomePage/index.tsx @@ -17,7 +17,6 @@ import { useTranslation } from 'react-i18next' import { navigate } from '../../lib/Navigation' import { decode } from 'nostr-tools/nip19' import { - getDirectMessages, getDirectMessagesCount, getGroupedDirectMessages, } from '../../Functions/DatabaseFunctions/DirectMessages' diff --git a/frontend/Pages/MyFeed/index.tsx b/frontend/Pages/MyFeed/index.tsx index 81f635c..4b4d8ee 100644 --- a/frontend/Pages/MyFeed/index.tsx +++ b/frontend/Pages/MyFeed/index.tsx @@ -80,49 +80,46 @@ export const MyFeed: React.FC = ({ navigation }) => { } } - const loadNotes: () => void = () => { + const loadNotes: () => void = async () => { if (database && publicKey) { - getMainNotes(database, publicKey, pageSize, true).then((notes) => { + relayPool?.unsubscribe(['homepage-reactions', 'homepage-replies', 'homepage-main']) + getMainNotes(database, publicKey, pageSize, true).then(async (notes) => { setNotes(notes) if (notes.length > 0) { - relayPool?.subscribe('homepage-contacts-meta', [ + const noteIds = notes.map((note) => note.id ?? '') + const messages: RelayFilters[] = [ { kinds: [Kind.Metadata], authors: notes.map((note) => note.pubkey ?? ''), }, - ]) - const noteIds = notes.map((note) => note.id ?? '') - getLastReaction(database, { eventIds: notes.map((note) => note.id ?? '') }).then( - (lastReaction) => { - relayPool?.subscribe('homepage-reactions', [ - { - kinds: [Kind.Reaction], - '#e': noteIds, - since: lastReaction?.created_at ?? 0, - }, - ]) - }, - ) + ] + const lastReaction = await getLastReaction(database, { + eventIds: notes.map((note) => note.id ?? ''), + }) + messages.push({ + kinds: [Kind.Reaction], + '#e': noteIds, + since: lastReaction?.created_at ?? 0, + }) const repostIds = notes.filter((note) => note.repost_id).map((note) => note.id ?? '') if (repostIds.length > 0) { - relayPool?.subscribe('homepage-reposts', [ - { - kinds: [Kind.Text], - '#e': repostIds, - }, - ]) + messages.push({ + kinds: [Kind.Text], + '#e': repostIds, + }) } - getLastReply(database, { eventIds: notes.map((note) => note.id ?? '') }).then( - (lastReply) => { - relayPool?.subscribe('homepage-replies', [ - { - kinds: [Kind.Text], - '#e': noteIds, - since: lastReply?.created_at ?? 0, - } - ]) + relayPool?.subscribe('homepage-contacts-meta', messages) + + const lastReply = await getLastReply(database, { + eventIds: notes.map((note) => note.id ?? ''), + }) + relayPool?.subscribe('homepage-contacts-replies', [ + { + kinds: [Kind.Text], + '#e': noteIds, + since: lastReply?.created_at ?? 0, }, - ) + ]) } }) } diff --git a/frontend/Pages/NotePage/index.tsx b/frontend/Pages/NotePage/index.tsx index 5229b29..f06332f 100644 --- a/frontend/Pages/NotePage/index.tsx +++ b/frontend/Pages/NotePage/index.tsx @@ -36,7 +36,7 @@ export const NotePage: React.FC = ({ route }) => { relayPool?.unsubscribe([ `meta-notepage${route.params.noteId}`, `notepage${route.params.noteId}`, - `notepage-replies-${route.params.noteId}` + `notepage-replies-${route.params.noteId}`, ]) }, []), ) diff --git a/frontend/Pages/NotificationsFeed/index.tsx b/frontend/Pages/NotificationsFeed/index.tsx index b2ea807..1ae7c75 100644 --- a/frontend/Pages/NotificationsFeed/index.tsx +++ b/frontend/Pages/NotificationsFeed/index.tsx @@ -93,37 +93,31 @@ export const NotificationsFeed: React.FC = () => { const loadNotes: () => void = () => { if (database && publicKey) { - getMentionNotes(database, publicKey, pageSize).then((notes) => { + getMentionNotes(database, publicKey, pageSize).then(async (notes) => { setNotes(notes) setRefreshing(false) if (notes.length > 0) { const notedIds = notes.map((note) => note.id ?? '') const authors = notes.map((note) => note.pubkey ?? '') + const lastReaction = await getLastReaction(database, { eventIds: notedIds }) + const lastReply = await getLastReply(database, { eventIds: notedIds }) relayPool?.subscribe('notification-meta', [ { kinds: [Kind.Metadata], authors, }, + { + kinds: [Kind.Reaction], + '#e': notedIds, + since: lastReaction?.created_at ?? 0, + }, + { + kinds: [Kind.Text], + '#e': notedIds, + since: lastReply?.created_at ?? 0, + }, ]) - getLastReaction(database, { eventIds: notedIds }).then((lastReaction) => { - relayPool?.subscribe('notification-reactions', [ - { - kinds: [Kind.Reaction], - '#e': notedIds, - since: lastReaction?.created_at ?? 0, - }, - ]) - }) - getLastReply(database, { eventIds: notedIds }).then((lastReply) => { - relayPool?.subscribe('notification-replies', [ - { - kinds: [Kind.Text], - '#e': notedIds, - since: lastReply?.created_at ?? 0, - }, - ]) - }) } }) } diff --git a/frontend/Pages/ProfileConfigPage/index.tsx b/frontend/Pages/ProfileConfigPage/index.tsx index 5bf5ecc..2af9f15 100644 --- a/frontend/Pages/ProfileConfigPage/index.tsx +++ b/frontend/Pages/ProfileConfigPage/index.tsx @@ -20,6 +20,7 @@ import { RelayPoolContext } from '../../Contexts/RelayPoolContext' import RBSheet from 'react-native-raw-bottom-sheet' import NostrosAvatar from '../../Components/NostrosAvatar' import { getUnixTime } from 'date-fns' +import { useFocusEffect } from '@react-navigation/native' export const ProfileConfigPage: React.FC = () => { const theme = useTheme() @@ -50,17 +51,21 @@ export const ProfileConfigPage: React.FC = () => { const [isPublishingProfile, setIsPublishingProfile] = useState() const { t } = useTranslation('common') - useEffect(() => { - if (database && publicKey) { - relayPool?.unsubscribeAll() - relayPool?.subscribe('loading-meta', [ - { - kinds: [Kind.Metadata], - authors: [publicKey], - }, - ]) - } - }, []) + useFocusEffect( + React.useCallback(() => { + if (database && publicKey) { + relayPool?.subscribe('loading-meta', [ + { + kinds: [Kind.Metadata], + authors: [publicKey], + }, + ]) + } + return () => { + relayPool?.unsubscribe(['loading-meta']) + } + }, []), + ) useEffect(() => { if (isPublishingProfile) { diff --git a/frontend/Pages/ProfilePage/index.tsx b/frontend/Pages/ProfilePage/index.tsx index 4edf2ac..696e0c9 100644 --- a/frontend/Pages/ProfilePage/index.tsx +++ b/frontend/Pages/ProfilePage/index.tsx @@ -54,9 +54,9 @@ export const ProfilePage: React.FC = ({ route }) => { return () => relayPool?.unsubscribe([ - `main-profile${route.params.pubKey}`, - `user-profile${route.params.pubKey}`, - `answers-profile${route.params.pubKey}`, + `profile${route.params.pubKey}`, + `profile-user${route.params.pubKey}`, + `profile-answers${route.params.pubKey}`, ]) }, []), ) @@ -101,7 +101,7 @@ export const ProfilePage: React.FC = ({ route }) => { setNotes(results) setRefreshing(false) if (results.length > 0) { - relayPool?.subscribe(`answers-profile${route.params.pubKey}`, [ + relayPool?.subscribe(`profile-answers${route.params.pubKey}`, [ { kinds: [Kind.Reaction, Kind.Text, Kind.RecommendRelay], '#e': results.map((note) => note.id ?? ''), @@ -114,7 +114,7 @@ export const ProfilePage: React.FC = ({ route }) => { } const subscribeProfile: () => Promise = async () => { - relayPool?.subscribe(`user-profile${route.params.pubKey}`, [ + relayPool?.subscribe(`profile-user${route.params.pubKey}`, [ { kinds: [Kind.Metadata, Kind.Contacts], authors: [route.params.pubKey], @@ -130,7 +130,7 @@ export const ProfilePage: React.FC = ({ route }) => { authors: [route.params.pubKey], limit: pageSize, } - relayPool?.subscribe(`main-profile${route.params.pubKey}`, [message]) + relayPool?.subscribe(`profile${route.params.pubKey}`, [message]) } const removeContact: () => void = () => { diff --git a/frontend/Pages/ReactionsFeed/index.tsx b/frontend/Pages/ReactionsFeed/index.tsx index 4ebab1f..bcd3348 100644 --- a/frontend/Pages/ReactionsFeed/index.tsx +++ b/frontend/Pages/ReactionsFeed/index.tsx @@ -75,45 +75,46 @@ export const ReactionsFeed: React.FC = ({ navigation }) => { } } - const loadNotes: () => void = () => { + const loadNotes: () => void = async () => { if (database && publicKey) { - getReactedNotes(database, publicKey, pageSize).then((notes) => { + relayPool?.unsubscribe(['homepage-reactions', 'homepage-replies', 'homepage-main']) + getReactedNotes(database, publicKey, pageSize).then(async (notes) => { setNotes(notes) if (notes.length > 0) { - relayPool?.subscribe('homepage-contacts-meta', [ + const noteIds = notes.map((note) => note.id ?? '') + const messages: RelayFilters[] = [ { kinds: [Kind.Metadata], authors: notes.map((note) => note.pubkey ?? ''), }, - ]) - const noteIds = notes.map((note) => note.id ?? '') - getLastReaction(database, { eventIds: notes.map((note) => note.id ?? '') }).then( - (lastReaction) => { - relayPool?.subscribe('homepage-reactions', [ - { - kinds: [Kind.Reaction], - '#e': noteIds, - since: lastReaction?.created_at ?? 0, - }, - ]) - }, - ) + ] + const lastReaction = await getLastReaction(database, { + eventIds: notes.map((note) => note.id ?? ''), + }) + messages.push({ + kinds: [Kind.Reaction], + '#e': noteIds, + since: lastReaction?.created_at ?? 0, + }) const repostIds = notes.filter((note) => note.repost_id).map((note) => note.id ?? '') - getLastReply(database, { eventIds: notes.map((note) => note.id ?? '') }).then( - (lastReply) => { - relayPool?.subscribe('homepage-replies', [ - { - kinds: [Kind.Text], - '#e': noteIds, - since: lastReply?.created_at ?? 0, - }, - { - kinds: [Kind.Text], - '#e': repostIds, - }, - ]) + if (repostIds.length > 0) { + messages.push({ + kinds: [Kind.Text], + '#e': repostIds, + }) + } + relayPool?.subscribe('homepage-contacts-meta', messages) + + const lastReply = await getLastReply(database, { + eventIds: notes.map((note) => note.id ?? ''), + }) + relayPool?.subscribe('homepage-contacts-replies', [ + { + kinds: [Kind.Text], + '#e': noteIds, + since: lastReply?.created_at ?? 0, }, - ) + ]) } }) } diff --git a/frontend/Pages/RelaysPage/index.tsx b/frontend/Pages/RelaysPage/index.tsx index f5ed4ae..5de0bd8 100644 --- a/frontend/Pages/RelaysPage/index.tsx +++ b/frontend/Pages/RelaysPage/index.tsx @@ -24,7 +24,8 @@ import { useFocusEffect } from '@react-navigation/native' export const RelaysPage: React.FC = () => { const defaultRelayInput = React.useMemo(() => 'wss://', []) - const { updateRelayItem, addRelayItem, removeRelayItem, relays, relayPool } = useContext(RelayPoolContext) + const { updateRelayItem, addRelayItem, removeRelayItem, relays, relayPool } = + useContext(RelayPoolContext) const { t } = useTranslation('common') const theme = useTheme() const bottomSheetAddRef = React.useRef(null) diff --git a/frontend/Pages/RepostsFeed/index.tsx b/frontend/Pages/RepostsFeed/index.tsx index 9d69909..7ca6cc4 100644 --- a/frontend/Pages/RepostsFeed/index.tsx +++ b/frontend/Pages/RepostsFeed/index.tsx @@ -75,45 +75,46 @@ export const RepostsFeed: React.FC = ({ navigation }) => { } } - const loadNotes: () => void = () => { + const loadNotes: () => void = async () => { if (database && publicKey) { - getRepostedNotes(database, publicKey, pageSize).then((notes) => { + relayPool?.unsubscribe(['homepage-reactions', 'homepage-replies', 'homepage-main']) + getRepostedNotes(database, publicKey, pageSize).then(async (notes) => { setNotes(notes) if (notes.length > 0) { - relayPool?.subscribe('homepage-contacts-meta', [ + const noteIds = notes.map((note) => note.id ?? '') + const messages: RelayFilters[] = [ { kinds: [Kind.Metadata], authors: notes.map((note) => note.pubkey ?? ''), }, - ]) - const noteIds = notes.map((note) => note.id ?? '') - getLastReaction(database, { eventIds: notes.map((note) => note.id ?? '') }).then( - (lastReaction) => { - relayPool?.subscribe('homepage-reactions', [ - { - kinds: [Kind.Reaction], - '#e': noteIds, - since: lastReaction?.created_at ?? 0, - }, - ]) - }, - ) + ] + const lastReaction = await getLastReaction(database, { + eventIds: notes.map((note) => note.id ?? ''), + }) + messages.push({ + kinds: [Kind.Reaction], + '#e': noteIds, + since: lastReaction?.created_at ?? 0, + }) const repostIds = notes.filter((note) => note.repost_id).map((note) => note.id ?? '') - getLastReply(database, { eventIds: notes.map((note) => note.id ?? '') }).then( - (lastReply) => { - relayPool?.subscribe('homepage-replies', [ - { - kinds: [Kind.Text], - '#e': noteIds, - since: lastReply?.created_at ?? 0, - }, - { - kinds: [Kind.Text], - '#e': repostIds, - }, - ]) + if (repostIds.length > 0) { + messages.push({ + kinds: [Kind.Text], + '#e': repostIds, + }) + } + relayPool?.subscribe('homepage-contacts-meta', messages) + + const lastReply = await getLastReply(database, { + eventIds: notes.map((note) => note.id ?? ''), + }) + relayPool?.subscribe('homepage-contacts-replies', [ + { + kinds: [Kind.Text], + '#e': noteIds, + since: lastReply?.created_at ?? 0, }, - ) + ]) } }) }