Invoice preview

This commit is contained in:
KoalaSat 2023-02-06 12:10:11 +01:00
parent 0b64a67baa
commit d2e30491ce
No known key found for this signature in database
GPG Key ID: 2F7F61C6146AB157
20 changed files with 379 additions and 244 deletions

View File

@ -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<TextContentProps> = ({ open, setOpen, event, user }) => {
export const LnPayment: React.FC<LnPaymentProps> = ({ 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<TextContentProps> = ({ 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<TextContentProps> = ({ 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 ? (
<>
<RBSheet
@ -147,40 +123,7 @@ export const LnPayment: React.FC<TextContentProps> = ({ open, setOpen, event, us
</Button>
</View>
</RBSheet>
<RBSheet
ref={bottomSheetInvoiceRef}
closeOnDragDown={true}
// height={630}
customStyles={rbSheetQrCustomStyles}
onClose={() => setOpen(false)}
>
<Card style={styles.qrContainer}>
<Card.Content>
<View style={styles.qr}>
<QRCode value={invoice} size={300} quietZone={8} />
</View>
<View style={styles.qrText}>
<Text>{monto} </Text>
{getSatoshiSymbol(23)}
</View>
{comment && (
<View style={styles.qrText}>
<Text>{comment}</Text>
</View>
)}
</Card.Content>
</Card>
<View style={styles.cardActions}>
<View style={styles.actionButton}>
<IconButton icon='content-copy' size={28} onPress={copyInvoice} />
<Text>{t('lnPayment.copy')}</Text>
</View>
<View style={styles.actionButton}>
<IconButton icon='wallet' size={28} onPress={openApp} />
<Text>{t('lnPayment.open')}</Text>
</View>
</View>
</RBSheet>
{invoice && <LnPreview invoice={invoice} setInvoice={setInvoice} />}
</>
) : (
<></>

View File

@ -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<LnPreviewProps> = ({ invoice, setInvoice }) => {
const theme = useTheme()
const { t } = useTranslation('common')
const { getSatoshiSymbol } = React.useContext(AppContext)
const bottomSheetInvoiceRef = React.useRef<RBSheet>(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 (
<>
<RBSheet
ref={bottomSheetInvoiceRef}
closeOnDragDown={true}
// height={630}
customStyles={rbSheetQrCustomStyles}
onClose={() => setInvoice(undefined)}
>
<Card style={styles.qrContainer}>
<Card.Content>
<View style={styles.qr}>
<QRCode value={invoice} size={300} quietZone={8} />
</View>
<View style={styles.qrText}>
<Text>{decodedLnUrl?.satoshis} </Text>
{getSatoshiSymbol(23)}
</View>
</Card.Content>
</Card>
<View style={styles.cardActions}>
<View style={styles.actionButton}>
<IconButton icon='content-copy' size={28} onPress={copyInvoice} />
<Text>{t('lnPayment.copy')}</Text>
</View>
<View style={styles.actionButton}>
<IconButton icon='wallet' size={28} onPress={openApp} />
<Text>{t('lnPayment.open')}</Text>
</View>
</View>
</RBSheet>
</>
)
}
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

View File

@ -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<TextContentProps> = ({
numberOfLines,
}) => {
const theme = useTheme()
const { database } = useContext(AppContext)
const { t } = useTranslation('common')
const { database, getSatoshiSymbol } = useContext(AppContext)
const [userNames, setUserNames] = useState<Record<number, string>>({})
const [loadedUsers, setLoadedUsers] = useState<number>(0)
const [url, setUrl] = useState<string>()
const [lnUrl, setLnUrl] = useState<string>()
const [invoice, setInvoice] = useState<string>()
const [decodedLnUrl, setDecodedLnUrl] = useState<
PaymentRequestObject & { tagsObject: TagsObject }
>()
const [linkPreview, setLinkPreview] = useState<string>()
const [linkType, setLinkType] = useState<string>()
const text = event?.content ?? content ?? ''
@ -61,6 +70,10 @@ export const TextContent: React.FC<TextContentProps> = ({
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<TextContentProps> = ({
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<TextContentProps> = ({
}
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<TextContentProps> = ({
}
return (
<View style={styles.previewCard}>
<Card onPress={() => handleUrlPress(url)}>
<FastImage
style={[
styles.cardCover,
{
backgroundColor: theme.colors.backdrop,
},
]}
source={{
uri: getRequireCover(),
priority: FastImage.priority.high,
}}
defaultSource={getDefaultCover()}
resizeMode={FastImage.resizeMode.contain}
/>
<Card.Content style={styles.previewContent}>
<Text variant='bodyMedium' numberOfLines={3}>
{/* {linkPreview?.title ?? linkPreview?.url ?? url} */}
{url}
</Text>
{/* {linkPreview?.description && (
<View>
{decodedLnUrl && (
<Card onPress={handleLnUrlPress}>
<Card.Title
title={t('textContent.invoice')}
subtitle={
<>
<Text>{decodedLnUrl.satoshis}</Text>
{getSatoshiSymbol(16)}
</>
}
left={(props) => (
<Avatar.Icon
{...props}
icon='lightning-bolt'
style={{
backgroundColor: '#F5D112',
}}
/>
)}
/>
</Card>
)}
{url && (
<View style={styles.previewCard}>
<Card onPress={() => handleUrlPress(url)}>
<FastImage
style={[
styles.cardCover,
{
backgroundColor: theme.colors.backdrop,
},
]}
source={{
uri: getRequireCover(),
priority: FastImage.priority.high,
}}
defaultSource={getDefaultCover()}
resizeMode={FastImage.resizeMode.contain}
/>
<Card.Content style={styles.previewContent}>
<Text variant='bodyMedium' numberOfLines={3}>
{/* {linkPreview?.title ?? linkPreview?.url ?? url} */}
{url}
</Text>
{/* {linkPreview?.description && (
<Text variant='bodySmall' numberOfLines={3}>
{linkPreview.description}
</Text>
)} */}
</Card.Content>
</Card>
</Card.Content>
</Card>
</View>
)}
{invoice && <LnPreview invoice={invoice} setInvoice={setInvoice} />}
</View>
)
}
@ -185,7 +233,7 @@ export const TextContent: React.FC<TextContentProps> = ({
return (
<View style={styles.container}>
<ParsedText
style={{ color: theme.colors.onSurfaceVariant }}
style={[styles.text, { color: theme.colors.onSurfaceVariant }]}
parse={[
{ type: 'url', style: styles.url, onPress: handleUrlPress, renderText: renderUrlText },
{ type: 'email', style: styles.email, onPress: handleUrlPress },
@ -200,6 +248,7 @@ export const TextContent: React.FC<TextContentProps> = ({
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*/,

View File

@ -30,7 +30,7 @@ export const updateAllRead: (db: QuickSQLiteConnection) => Promise<QueryResult |
export const getDirectMessagesCount: (
db: QuickSQLiteConnection,
pubKey: string
pubKey: string,
) => Promise<number> = async (db, pubKey) => {
const repliesQuery = `
SELECT

View File

@ -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.",

View File

@ -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",

View File

@ -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",

View File

@ -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é",

View File

@ -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.",

View File

@ -127,12 +127,8 @@ export const HomeNavigator: React.FC = () => {
onPress={() => onPressQuestion(route.name)}
/>
)}
{historyKey?.includes('messages-') && (
<Appbar.Action
icon='check-all'
isLeading
onPress={() => onPressCheckAll(route.name)}
/>
{['Landing'].includes(route.name) && historyKey?.includes('messages-') && (
<Appbar.Action icon='check-all' isLeading onPress={() => onPressCheckAll()} />
)}
</Appbar.Header>
)

View File

@ -96,21 +96,20 @@ export const GlobalFeed: React.FC<GlobalFeedProps> = ({ 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)
}
})
}

View File

@ -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'

View File

@ -80,49 +80,46 @@ export const MyFeed: React.FC<MyFeedProps> = ({ 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,
},
)
])
}
})
}

View File

@ -36,7 +36,7 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
relayPool?.unsubscribe([
`meta-notepage${route.params.noteId}`,
`notepage${route.params.noteId}`,
`notepage-replies-${route.params.noteId}`
`notepage-replies-${route.params.noteId}`,
])
}, []),
)

View File

@ -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,
},
])
})
}
})
}

View File

@ -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<string>()
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) {

View File

@ -54,9 +54,9 @@ export const ProfilePage: React.FC<ProfilePageProps> = ({ 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<ProfilePageProps> = ({ 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<ProfilePageProps> = ({ route }) => {
}
const subscribeProfile: () => Promise<void> = 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<ProfilePageProps> = ({ 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 = () => {

View File

@ -75,45 +75,46 @@ export const ReactionsFeed: React.FC<ReactionsFeedProps> = ({ 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,
},
)
])
}
})
}

View File

@ -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<RBSheet>(null)

View File

@ -75,45 +75,46 @@ export const RepostsFeed: React.FC<RepostsFeedProps> = ({ 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,
},
)
])
}
})
}