mirror of
https://github.com/KoalaSat/nostros.git
synced 2024-09-29 06:30:47 +00:00
Invoice preview
This commit is contained in:
parent
0b64a67baa
commit
d2e30491ce
@ -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} />}
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
|
130
frontend/Components/LnPreview/index.tsx
Normal file
130
frontend/Components/LnPreview/index.tsx
Normal 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
|
@ -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*/,
|
||||
|
@ -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
|
||||
|
@ -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.",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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é",
|
||||
|
@ -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.",
|
||||
|
@ -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>
|
||||
)
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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'
|
||||
|
@ -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,
|
||||
},
|
||||
)
|
||||
])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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}`,
|
||||
])
|
||||
}, []),
|
||||
)
|
||||
|
@ -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,
|
||||
},
|
||||
])
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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 = () => {
|
||||
|
@ -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,
|
||||
},
|
||||
)
|
||||
])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
},
|
||||
)
|
||||
])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user