Relay drawer (#240)

This commit is contained in:
KoalaSat 2023-02-03 18:29:43 +00:00 committed by GitHub
commit d20fa83dff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 539 additions and 260 deletions

View File

@ -21,6 +21,7 @@ module.exports = {
'react/prop-types': 'off', 'react/prop-types': 'off',
'react/react-in-jsx-scope': 'off', 'react/react-in-jsx-scope': 'off',
'@typescript-eslint/strict-boolean-expressions': 'off', '@typescript-eslint/strict-boolean-expressions': 'off',
'@typescript-eslint/no-confusing-void-expression': 'off',
'@typescript-eslint/no-dynamic-delete': 'off', '@typescript-eslint/no-dynamic-delete': 'off',
'@typescript-eslint/no-floating-promises': 'off', '@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/no-misused-promises': 'off', '@typescript-eslint/no-misused-promises': 'off',

View File

@ -19,7 +19,7 @@
android:launchMode="singleTask" android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustResize"
android:exported="true"> android:exported="true">
<intent-filter android:label="filter_react_native"> <intent-filter android:label="">
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />

View File

@ -3,6 +3,7 @@ import { StyleSheet, View } from 'react-native'
import { Avatar as PaperAvatar, useTheme } from 'react-native-paper' import { Avatar as PaperAvatar, useTheme } from 'react-native-paper'
import { validImageUrl } from '../../Functions/NativeFunctions' import { validImageUrl } from '../../Functions/NativeFunctions'
import FastImage from 'react-native-fast-image' import FastImage from 'react-native-fast-image'
import { formatPubKey } from '../../Functions/RelayFunctions/Users'
interface NostrosAvatarProps { interface NostrosAvatarProps {
pubKey?: string pubKey?: string
@ -20,7 +21,7 @@ export const NostrosAvatar: React.FC<NostrosAvatarProps> = ({
lud06, lud06,
}) => { }) => {
const theme = useTheme() const theme = useTheme()
const displayName = name && name !== '' ? name : pubKey ?? '' const displayName = name && name !== '' ? name : formatPubKey(pubKey) ?? ''
const hasLud06 = lud06 && lud06 !== '' const hasLud06 = lud06 && lud06 !== ''
const lud06IconSize = size / 2.85 const lud06IconSize = size / 2.85

View File

@ -8,7 +8,7 @@ import {
Note, Note,
NoteRelay, NoteRelay,
} from '../../Functions/DatabaseFunctions/Notes' } from '../../Functions/DatabaseFunctions/Notes'
import { StyleSheet, View } from 'react-native' import { StyleSheet, TouchableNativeFeedback, View } from 'react-native'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext' import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { AppContext } from '../../Contexts/AppContext' import { AppContext } from '../../Contexts/AppContext'
import { t } from 'i18next' import { t } from 'i18next'
@ -34,14 +34,12 @@ import {
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons' import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import { REGEX_SOCKET_LINK } from '../../Constants/Relay' import { REGEX_SOCKET_LINK } from '../../Constants/Relay'
import { push } from '../../lib/Navigation' import { push } from '../../lib/Navigation'
import { User } from '../../Functions/DatabaseFunctions/Users'
import { Kind } from 'nostr-tools' import { Kind } from 'nostr-tools'
import ProfileData from '../ProfileData' import ProfileData from '../ProfileData'
import { relayToColor } from '../../Functions/NativeFunctions' import { relayToColor } from '../../Functions/NativeFunctions'
interface NoteCardProps { interface NoteCardProps {
note?: Note note?: Note
onPressUser?: (user: User) => void
showAvatarImage?: boolean showAvatarImage?: boolean
showAnswerData?: boolean showAnswerData?: boolean
showAction?: boolean showAction?: boolean
@ -60,14 +58,13 @@ export const NoteCard: React.FC<NoteCardProps> = ({
showActionCount = true, showActionCount = true,
showPreview = true, showPreview = true,
showRepostPreview = true, showRepostPreview = true,
onPressUser = () => {},
numberOfLines, numberOfLines,
mode = 'elevated', mode = 'elevated',
}) => { }) => {
const theme = useTheme() const theme = useTheme()
const { publicKey, privateKey } = React.useContext(UserContext) const { publicKey, privateKey } = React.useContext(UserContext)
const { relayPool, lastEventId } = useContext(RelayPoolContext) const { relayPool, lastEventId, setDisplayrelayDrawer } = useContext(RelayPoolContext)
const { database, showSensitive } = useContext(AppContext) const { database, showSensitive, setDisplayUserDrawer } = useContext(AppContext)
const [relayAdded, setRelayAdded] = useState<boolean>(false) const [relayAdded, setRelayAdded] = useState<boolean>(false)
const [positiveReactions, setPositiveReactions] = useState<number>(0) const [positiveReactions, setPositiveReactions] = useState<number>(0)
const [negaiveReactions, setNegativeReactions] = useState<number>(0) const [negaiveReactions, setNegativeReactions] = useState<number>(0)
@ -171,7 +168,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
) : ( ) : (
<TextContent <TextContent
event={note} event={note}
onPressUser={onPressUser} onPressUser={(user) => setDisplayUserDrawer(user.id)}
showPreview={showPreview} showPreview={showPreview}
numberOfLines={numberOfLines} numberOfLines={numberOfLines}
/> />
@ -266,7 +263,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
return note ? ( return note ? (
<Card mode={mode}> <Card mode={mode}>
<Card.Content style={styles.title}> <Card.Content style={styles.title}>
<TouchableRipple onPress={() => onPressUser({ id: note.pubkey, name: note.name })}> <TouchableRipple onPress={() => setDisplayUserDrawer(note.pubkey)}>
<ProfileData <ProfileData
username={note?.name} username={note?.name}
publicKey={note.pubkey} publicKey={note.pubkey}
@ -283,13 +280,13 @@ export const NoteCard: React.FC<NoteCardProps> = ({
<IconButton <IconButton
icon='dots-vertical' icon='dots-vertical'
size={24} size={24}
onPress={() => onPressUser({ id: note.pubkey, name: note.name })} onPress={() => setDisplayUserDrawer(note.pubkey)}
/> />
</View> </View>
)} )}
</Card.Content> </Card.Content>
{getNoteContent()} {getNoteContent()}
{showAction && !note?.blocked > 0 && ( {showAction && (
<Card.Content style={[styles.bottomActions, { borderColor: theme.colors.onSecondary }]}> <Card.Content style={[styles.bottomActions, { borderColor: theme.colors.onSecondary }]}>
<Button <Button
icon={() => ( icon={() => (
@ -361,8 +358,11 @@ export const NoteCard: React.FC<NoteCardProps> = ({
)} )}
<Card.Content style={styles.relayList}> <Card.Content style={styles.relayList}>
{relays.map((relay, index) => ( {relays.map((relay, index) => (
<View <TouchableNativeFeedback
onPress={() => setDisplayrelayDrawer(relay.relay_url)}
key={relay.relay_url} key={relay.relay_url}
>
<View
style={[ style={[
styles.relay, styles.relay,
{ backgroundColor: relayToColor(relay.relay_url) }, { backgroundColor: relayToColor(relay.relay_url) },
@ -370,6 +370,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
index === relays.length - 1 ? { borderBottomRightRadius: 50 } : {}, index === relays.length - 1 ? { borderBottomRightRadius: 50 } : {},
]} ]}
/> />
</TouchableNativeFeedback>
))} ))}
</Card.Content> </Card.Content>
</Card> </Card>
@ -388,7 +389,7 @@ const styles = StyleSheet.create({
}, },
relay: { relay: {
flex: 1, flex: 1,
height: 6, height: 10,
}, },
titleUsername: { titleUsername: {
fontWeight: 'bold', fontWeight: 'bold',

View File

@ -23,17 +23,13 @@ import ProfileData from '../ProfileData'
import QRCode from 'react-native-qrcode-svg' import QRCode from 'react-native-qrcode-svg'
interface ProfileCardProps { interface ProfileCardProps {
userPubKey: string
bottomSheetRef: React.RefObject<RBSheet> bottomSheetRef: React.RefObject<RBSheet>
showImages?: boolean showImages?: boolean
} }
export const ProfileCard: React.FC<ProfileCardProps> = ({ export const ProfileCard: React.FC<ProfileCardProps> = ({ bottomSheetRef, showImages = true }) => {
userPubKey,
bottomSheetRef,
showImages = true,
}) => {
const theme = useTheme() const theme = useTheme()
const { displayUserDrawer } = React.useContext(AppContext)
const bottomSheetShareRef = React.useRef<RBSheet>(null) const bottomSheetShareRef = React.useRef<RBSheet>(null)
const { database } = React.useContext(AppContext) const { database } = React.useContext(AppContext)
const { publicKey } = React.useContext(UserContext) const { publicKey } = React.useContext(UserContext)
@ -44,7 +40,7 @@ export const ProfileCard: React.FC<ProfileCardProps> = ({
const [isContact, setIsContact] = React.useState<boolean>() const [isContact, setIsContact] = React.useState<boolean>()
const [showNotification, setShowNotification] = React.useState<undefined | string>() const [showNotification, setShowNotification] = React.useState<undefined | string>()
const [qrCode, setQrCode] = React.useState<any>() const [qrCode, setQrCode] = React.useState<any>()
const nPub = React.useMemo(() => getNpub(userPubKey), [userPubKey]) const nPub = React.useMemo(() => getNpub(displayUserDrawer), [displayUserDrawer])
const username = React.useMemo(() => usernamePubKey(user?.name ?? '', nPub), [nPub, user]) const username = React.useMemo(() => usernamePubKey(user?.name ?? '', nPub), [nPub, user])
React.useEffect(() => { React.useEffect(() => {
@ -52,8 +48,8 @@ export const ProfileCard: React.FC<ProfileCardProps> = ({
}, []) }, [])
const onChangeBlockUser: () => void = () => { const onChangeBlockUser: () => void = () => {
if (database && blocked !== undefined) { if (database && blocked !== undefined && displayUserDrawer) {
updateUserBlock(userPubKey, database, !blocked).then(() => { updateUserBlock(displayUserDrawer, database, !blocked).then(() => {
setBlocked(blocked === 0 ? 1 : 0) setBlocked(blocked === 0 ? 1 : 0)
loadUser() loadUser()
}) })
@ -61,8 +57,8 @@ export const ProfileCard: React.FC<ProfileCardProps> = ({
} }
const removeContact: () => void = () => { const removeContact: () => void = () => {
if (relayPool && database && publicKey) { if (relayPool && database && publicKey && displayUserDrawer) {
updateUserContact(userPubKey, database, false).then(() => { updateUserContact(displayUserDrawer, database, false).then(() => {
populatePets(relayPool, database, publicKey) populatePets(relayPool, database, publicKey)
setIsContact(false) setIsContact(false)
setShowNotification('contactRemoved') setShowNotification('contactRemoved')
@ -71,8 +67,8 @@ export const ProfileCard: React.FC<ProfileCardProps> = ({
} }
const addContact: () => void = () => { const addContact: () => void = () => {
if (relayPool && database && publicKey) { if (relayPool && database && publicKey && displayUserDrawer) {
updateUserContact(userPubKey, database, true).then(() => { updateUserContact(displayUserDrawer, database, true).then(() => {
populatePets(relayPool, database, publicKey) populatePets(relayPool, database, publicKey)
setIsContact(true) setIsContact(true)
setShowNotification('contactAdded') setShowNotification('contactAdded')
@ -81,14 +77,14 @@ export const ProfileCard: React.FC<ProfileCardProps> = ({
} }
const loadUser: () => void = () => { const loadUser: () => void = () => {
if (database) { if (database && displayUserDrawer) {
getUser(userPubKey, database).then((result) => { getUser(displayUserDrawer, database).then((result) => {
if (result) { if (result) {
setUser(result) setUser(result)
setBlocked(result.blocked) setBlocked(result.blocked)
setIsContact(result?.contact) setIsContact(result?.contact)
} else { } else {
setUser({ id: userPubKey }) setUser({ id: displayUserDrawer })
setBlocked(0) setBlocked(0)
} }
}) })
@ -97,7 +93,7 @@ export const ProfileCard: React.FC<ProfileCardProps> = ({
const goToProfile: () => void = () => { const goToProfile: () => void = () => {
bottomSheetRef.current?.close() bottomSheetRef.current?.close()
push('Profile', { pubKey: userPubKey, title: username }) push('Profile', { pubKey: displayUserDrawer, title: username })
} }
const bottomSheetStyles = React.useMemo(() => { const bottomSheetStyles = React.useMemo(() => {
@ -123,7 +119,7 @@ export const ProfileCard: React.FC<ProfileCardProps> = ({
<View style={styles.cardUserMain}> <View style={styles.cardUserMain}>
<ProfileData <ProfileData
username={user?.name} username={user?.name}
publicKey={user?.id ?? userPubKey} publicKey={user?.id ?? displayUserDrawer}
validNip05={user?.valid_nip05} validNip05={user?.valid_nip05}
nip05={user?.nip05} nip05={user?.nip05}
lud06={user?.lnurl} lud06={user?.lnurl}
@ -151,7 +147,7 @@ export const ProfileCard: React.FC<ProfileCardProps> = ({
</Card.Content> </Card.Content>
</Card> </Card>
<View style={styles.mainLayout}> <View style={styles.mainLayout}>
{userPubKey !== publicKey && ( {displayUserDrawer !== publicKey && (
<View style={styles.actionButton}> <View style={styles.actionButton}>
<IconButton <IconButton
icon={isContact ? 'account-multiple-remove-outline' : 'account-multiple-plus-outline'} icon={isContact ? 'account-multiple-remove-outline' : 'account-multiple-plus-outline'}
@ -168,7 +164,7 @@ export const ProfileCard: React.FC<ProfileCardProps> = ({
icon='message-plus-outline' icon='message-plus-outline'
size={28} size={28}
onPress={() => { onPress={() => {
navigate('Conversation', { pubKey: userPubKey, title: username }) navigate('Conversation', { pubKey: displayUserDrawer, title: username })
bottomSheetRef.current?.close() bottomSheetRef.current?.close()
}} }}
/> />

View File

@ -0,0 +1,292 @@
import { t } from 'i18next'
import * as React from 'react'
import { StyleSheet, Switch, View } from 'react-native'
import { Divider, IconButton, List, Snackbar, Text } from 'react-native-paper'
import { AppContext } from '../../Contexts/AppContext'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import RBSheet from 'react-native-raw-bottom-sheet'
import { getRelay, Relay, RelayInfo } from '../../Functions/DatabaseFunctions/Relays'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import { relayToColor } from '../../Functions/NativeFunctions'
import axios from 'axios'
import { ScrollView } from 'react-native-gesture-handler'
import Clipboard from '@react-native-clipboard/clipboard'
import Logo from '../Logo'
interface RelayCardProps {
url?: string
bottomSheetRef: React.RefObject<RBSheet>
}
export const RelayCard: React.FC<RelayCardProps> = ({ url, bottomSheetRef }) => {
const { updateRelayItem } = React.useContext(RelayPoolContext)
const { database } = React.useContext(AppContext)
const [relay, setRelay] = React.useState<Relay>()
const [uri, setUri] = React.useState<string>()
const [relayInfo, setRelayInfo] = React.useState<RelayInfo>()
const [showNotification, setShowNotification] = React.useState<string>()
const [moreInfo, setMoreInfo] = React.useState<boolean>(false)
React.useEffect(() => {
loadRelay()
}, [])
React.useEffect(() => {
if (relay) {
setUri(relay.url.split('wss://')[1]?.split('/')[0])
}
}, [relay])
React.useEffect(() => {
if (uri && moreInfo) {
const headers = {
Accept: 'application/nostr+json',
}
axios
.get('http://' + uri, {
headers,
})
.then((response) => {
setRelayInfo(response.data)
})
.catch((e) => {
console.log(e)
})
}
}, [moreInfo])
const activeRelay: () => void = () => {
if (relay) {
const newRelay = relay
newRelay.active = 1
newRelay.global_feed = 1
updateRelayItem(newRelay).then(() => {
setShowNotification('active')
})
setRelay(newRelay)
}
}
const desactiveRelay: () => void = () => {
if (relay) {
const newRelay = relay
newRelay.active = 0
newRelay.global_feed = 0
updateRelayItem(newRelay).then(() => {
setShowNotification('desactive')
})
setRelay(newRelay)
}
}
const activeGlobalFeedRelay: () => void = () => {
if (relay) {
const newRelay = relay
newRelay.active = 1
newRelay.global_feed = 1
updateRelayItem(newRelay).then(() => {
setShowNotification('globalFeedActive')
})
setRelay(newRelay)
}
}
const desactiveGlobalFeedRelay: () => void = () => {
if (relay) {
const newRelay = relay
newRelay.global_feed = 0
updateRelayItem(relay).then(() => {
setShowNotification('globalFeedActiveUnactive')
})
setRelay(newRelay)
}
}
const loadRelay: () => void = () => {
if (database && url) {
getRelay(database, url).then((result) => {
if (result) setRelay(result)
})
}
}
return relay ? (
<View>
<View style={styles.relayDescription}>
<View style={styles.relayName}>
<MaterialCommunityIcons
style={styles.relayColor}
name='circle'
color={relayToColor(relay.url)}
/>
<Text>{relay.url.split('wss://')[1]?.split('/')[0]}</Text>
</View>
<Text>{relay.url}</Text>
<View style={styles.moreInfo}>
{!moreInfo && (
<Text style={styles.moreInfoText} onPress={() => setMoreInfo(true)}>
{t('relayCard.moreInfo')}
</Text>
)}
{moreInfo && (
<Text style={styles.moreInfoText} onPress={() => setMoreInfo(false)}>
{t('relayCard.lessInfo')}
</Text>
)}
{moreInfo && (
<>
{relayInfo ? (
<ScrollView>
<View style={styles.moreInfoItem}>
<Text variant='titleMedium'>{t('relayCard.description')}</Text>
<Text>{relayInfo?.description}</Text>
</View>
<View style={styles.moreInfoItem}>
<Text variant='titleMedium'>{t('relayCard.pubkey')}</Text>
<Text
onPress={() => {
if (relayInfo?.pubkey) {
Clipboard.setString(relayInfo?.pubkey)
setShowNotification('pubkeyCopied')
}
}}
>
{relayInfo?.pubkey}
</Text>
</View>
<View style={styles.moreInfoItem}>
<Text variant='titleMedium'>{t('relayCard.contact')}</Text>
<Text
onPress={() => {
if (relayInfo?.contact) {
Clipboard.setString(relayInfo?.contact)
setShowNotification('contactCopied')
}
}}
>
{relayInfo?.contact}
</Text>
</View>
<View style={styles.moreInfoItem}>
<Text variant='titleMedium'>{t('relayCard.supportedNips')}</Text>
<Text>{relayInfo?.supported_nips.join(', ')}</Text>
</View>
<View style={styles.moreInfoItem}>
<Text variant='titleMedium'>{t('relayCard.software')}</Text>
<Text>{relayInfo?.software}</Text>
</View>
<View style={styles.moreInfoItem}>
<Text variant='titleMedium'>{t('relayCard.version')}</Text>
<Text>{relayInfo?.version}</Text>
</View>
</ScrollView>
) : (
<View style={styles.loading}>
<Logo onlyIcon size='medium' />
<Text variant='titleLarge'>{'relayCard.obtainingInfo'}</Text>
</View>
)}
</>
)}
</View>
</View>
<Divider />
<View>
<List.Item
title={t('relayCard.globalFeed')}
right={() => (
<Switch
value={relay.global_feed !== undefined && relay.global_feed > 0}
onValueChange={() =>
relay.global_feed ? desactiveGlobalFeedRelay() : activeGlobalFeedRelay()
}
/>
)}
/>
<List.Item
title={t('relayCard.active')}
right={() => (
<Switch
value={relay.active !== undefined && relay.active > 0}
onValueChange={() => (relay.active ? desactiveRelay() : activeRelay())}
/>
)}
/>
</View>
<Divider />
<View style={styles.actions}>
<View style={styles.actionButton}>
<IconButton
icon={'share-variant-outline'}
size={28}
onPress={() => {
Clipboard.setString(relay.url)
setShowNotification('urlCopied')
}}
/>
<Text>{t('relayCard.share')}</Text>
</View>
</View>
{showNotification && (
<Snackbar
style={styles.snackbar}
visible={showNotification !== undefined}
duration={Snackbar.DURATION_SHORT}
onIconPress={() => setShowNotification(undefined)}
onDismiss={() => setShowNotification(undefined)}
>
{t(`relayCard.notifications.${showNotification}`)}
</Snackbar>
)}
</View>
) : (
<></>
)
}
const styles = StyleSheet.create({
container: {
padding: 16,
},
loading: {
height: 372,
justifyContent: 'center',
alignItems: 'center',
},
moreInfoItem: {
paddingTop: 16,
},
relayColor: {
paddingTop: 5,
paddingRight: 8,
},
snackbar: {
marginBottom: 85,
},
moreInfo: {
paddingTop: 16,
},
moreInfoText: {
textDecorationLine: 'underline',
},
relayName: {
flexDirection: 'row',
},
relayDescription: {
padding: 16,
justifyContent: 'space-between',
},
actions: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
actionButton: {
justifyContent: 'center',
alignItems: 'center',
marginBottom: 4,
width: '33%',
},
})
export default RelayCard

View File

@ -31,6 +31,8 @@ export interface AppContextProps {
clipboardNip21?: string clipboardNip21?: string
setClipboardNip21: (clipboardNip21: string | undefined) => void setClipboardNip21: (clipboardNip21: string | undefined) => void
checkClipboard: () => void checkClipboard: () => void
displayUserDrawer?: string
setDisplayUserDrawer: (displayUserDrawer: string | undefined) => void
} }
export interface AppContextProviderProps { export interface AppContextProviderProps {
@ -46,9 +48,10 @@ export const initialAppContext: AppContextProps = {
showPublicImages: false, showPublicImages: false,
setShowPublicImages: () => {}, setShowPublicImages: () => {},
language: language:
Platform.OS === 'ios' (Platform.OS === 'ios'
? NativeModules.SettingsManager.settings.AppleLocale ? NativeModules.SettingsManager.settings.AppleLocale
: NativeModules.I18nManager.localeIdentifier, : NativeModules.I18nManager.localeIdentifier
)?.split('_')[0] ?? 'en',
setLanguage: () => {}, setLanguage: () => {},
showSensitive: false, showSensitive: false,
setShowSensitive: () => {}, setShowSensitive: () => {},
@ -60,6 +63,7 @@ export const initialAppContext: AppContextProps = {
getImageHostingService: () => '', getImageHostingService: () => '',
getSatoshiSymbol: () => <></>, getSatoshiSymbol: () => <></>,
setClipboardNip21: () => {}, setClipboardNip21: () => {},
setDisplayUserDrawer: () => {},
} }
export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.Element => { export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.Element => {
@ -79,6 +83,7 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
const [loadingDb, setLoadingDb] = useState<boolean>(initialAppContext.loadingDb) const [loadingDb, setLoadingDb] = useState<boolean>(initialAppContext.loadingDb)
const [clipboardLoads, setClipboardLoads] = React.useState<string[]>([]) const [clipboardLoads, setClipboardLoads] = React.useState<string[]>([])
const [clipboardNip21, setClipboardNip21] = React.useState<string>() const [clipboardNip21, setClipboardNip21] = React.useState<string>()
const [displayUserDrawer, setDisplayUserDrawer] = React.useState<string>()
useEffect(() => { useEffect(() => {
const handleChange = AppState.addEventListener('change', (changedState) => { const handleChange = AppState.addEventListener('change', (changedState) => {
@ -172,6 +177,8 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
return ( return (
<AppContext.Provider <AppContext.Provider
value={{ value={{
displayUserDrawer,
setDisplayUserDrawer,
language, language,
setLanguage, setLanguage,
checkClipboard, checkClipboard,

View File

@ -11,6 +11,8 @@ export interface RelayPoolContextProps {
relayPool?: RelayPool relayPool?: RelayPool
setRelayPool: (relayPool: RelayPool) => void setRelayPool: (relayPool: RelayPool) => void
lastEventId?: string lastEventId?: string
setDisplayrelayDrawer: (displayRelayDrawer: string | undefined) => void
displayRelayDrawer?: string
lastConfirmationtId?: string lastConfirmationtId?: string
relays: Relay[] relays: Relay[]
addRelayItem: (relay: Relay) => Promise<void> addRelayItem: (relay: Relay) => Promise<void>
@ -34,6 +36,7 @@ export const initialRelayPoolContext: RelayPoolContextProps = {
removeRelayItem: async () => await new Promise(() => {}), removeRelayItem: async () => await new Promise(() => {}),
updateRelayItem: async () => await new Promise(() => {}), updateRelayItem: async () => await new Promise(() => {}),
relays: [], relays: [],
setDisplayrelayDrawer: () => {},
} }
export const RelayPoolContextProvider = ({ export const RelayPoolContextProvider = ({
@ -48,6 +51,7 @@ export const RelayPoolContextProvider = ({
const [lastEventId, setLastEventId] = useState<string>('') const [lastEventId, setLastEventId] = useState<string>('')
const [lastConfirmationtId, setLastConfirmationId] = useState<string>('') const [lastConfirmationtId, setLastConfirmationId] = useState<string>('')
const [relays, setRelays] = React.useState<Relay[]>([]) const [relays, setRelays] = React.useState<Relay[]>([])
const [displayRelayDrawer, setDisplayrelayDrawer] = React.useState<string>()
const changeEventIdHandler: (event: WebsocketEvent) => void = (event) => { const changeEventIdHandler: (event: WebsocketEvent) => void = (event) => {
setLastEventId(event.eventId) setLastEventId(event.eventId)
@ -151,6 +155,8 @@ export const RelayPoolContextProvider = ({
return ( return (
<RelayPoolContext.Provider <RelayPoolContext.Provider
value={{ value={{
displayRelayDrawer,
setDisplayrelayDrawer,
relayPoolReady, relayPoolReady,
relayPool, relayPool,
setRelayPool, setRelayPool,

View File

@ -8,6 +8,16 @@ export interface Relay {
global_feed?: number global_feed?: number
} }
export interface RelayInfo {
name: string
description: string
pubkey: string
contact: string
supported_nips: string[]
software: string
version: string
}
const databaseToEntity: (object: any) => Relay = (object) => { const databaseToEntity: (object: any) => Relay = (object) => {
return object as Relay return object as Relay
} }
@ -31,6 +41,17 @@ export const getRelays: (db: QuickSQLiteConnection) => Promise<Relay[]> = async
return relays return relays
} }
export const getRelay: (db: QuickSQLiteConnection, url: string) => Promise<Relay> = async (
db,
url,
) => {
const notesQuery = 'SELECT * FROM nostros_relays WHERE url = ?;'
const resultSet = await db.execute(notesQuery, [url])
const items: object[] = getItems(resultSet)
const relays: Relay[] = items.map((object) => databaseToEntity(object))
return relays[0]
}
export const createRelay: (db: QuickSQLiteConnection, url: string) => Promise<QueryResult> = async ( export const createRelay: (db: QuickSQLiteConnection, url: string) => Promise<QueryResult> = async (
db, db,
url, url,

View File

@ -152,6 +152,29 @@
"newMessages": "{{newNotesCount}} neue Nachrichten. Zum Aktualisieren wischen.", "newMessages": "{{newNotesCount}} neue Nachrichten. Zum Aktualisieren wischen.",
"myFeed": "Mein Feed" "myFeed": "Mein Feed"
}, },
"relayCard": {
"moreInfo": "More info",
"lessInfo": "Less info",
"globalFeed": "Global Feed",
"active": "Active",
"share": "Share",
"pubkey": "Public key",
"contact": "Contact",
"supportedNips": "Supported NIPs",
"software": "Sowftware",
"version": "Version",
"description": "Description",
"obtainingInfo": "Obtaining relay information",
"notifications": {
"active": "Relay actived.",
"desactive": "Relay desactivated.",
"globalFeedActive": "Global feed enabled.",
"globalFeedActiveUnactive": "Global feed disabled.",
"pubkeyCopied": "Public key copied.",
"contactCopied": "Contact copied.",
"urlCopied": "URL copied."
}
},
"relaysPage": { "relaysPage": {
"relayName": "Address", "relayName": "Address",
"globalFeed": "Global feed", "globalFeed": "Global feed",

View File

@ -184,6 +184,29 @@
"alreadyExists": "Relay already exists." "alreadyExists": "Relay already exists."
} }
}, },
"relayCard": {
"moreInfo": "More info",
"lessInfo": "Less info",
"globalFeed": "Global Feed",
"active": "Active",
"share": "Share",
"pubkey": "Public key",
"contact": "Contact",
"supportedNips": "Supported NIPs",
"software": "Sowftware",
"version": "Version",
"description": "Description",
"obtainingInfo": "Obtaining relay information",
"notifications": {
"active": "Relay actived.",
"desactive": "Relay desactivated.",
"globalFeedActive": "Global feed enabled.",
"globalFeedActiveUnactive": "Global feed disabled.",
"pubkeyCopied": "Public key copied.",
"contactCopied": "Contact copied.",
"urlCopied": "URL copied."
}
},
"profileConfigPage": { "profileConfigPage": {
"notifications": { "notifications": {
"nsecCopied": "Secret key copied.", "nsecCopied": "Secret key copied.",

View File

@ -152,6 +152,29 @@
"newMessages": "{{newNotesCount}} notas nuevas. Desliza para refrescar.", "newMessages": "{{newNotesCount}} notas nuevas. Desliza para refrescar.",
"myFeed": "Mi feed" "myFeed": "Mi feed"
}, },
"relayCard": {
"moreInfo": "Más información",
"lessInfo": "Menos información",
"globalFeed": "Feed Global",
"active": "Activo",
"share": "Compartir",
"pubkey": "Clave pública",
"contact": "Contacto",
"supportedNips": "NIPs soportadas",
"software": "Sowftware",
"version": "Versión",
"description": "Descripción",
"obtainingInfo": "Obteniendo información del relay",
"notifications": {
"active": "Relay activado.",
"desactive": "Relay desactivado.",
"globalFeedActive": "Feed global activado.",
"globalFeedActiveUnactive": "Feed Global desactivado.",
"pubkeyCopied": "Clave pública copiada.",
"contactCopied": "Contactp copiado.",
"urlCopied": "URL copiada."
}
},
"relaysPage": { "relaysPage": {
"relayName": "Dirección", "relayName": "Dirección",
"globalFeed": "Feed global", "globalFeed": "Feed global",

View File

@ -151,6 +151,29 @@
"newMessages": "{{newNotesCount}} nouvelles notes. Balayez pour recharger.", "newMessages": "{{newNotesCount}} nouvelles notes. Balayez pour recharger.",
"myFeed": "Mon flux" "myFeed": "Mon flux"
}, },
"relayCard": {
"moreInfo": "More info",
"lessInfo": "Less info",
"globalFeed": "Global Feed",
"active": "Active",
"share": "Share",
"pubkey": "Public key",
"contact": "Contact",
"supportedNips": "Supported NIPs",
"software": "Sowftware",
"version": "Version",
"description": "Description",
"obtainingInfo": "Obtaining relay information",
"notifications": {
"active": "Relay actived.",
"desactive": "Relay desactivated.",
"globalFeedActive": "Global feed enabled.",
"globalFeedActiveUnactive": "Global feed disabled.",
"pubkeyCopied": "Public key copied.",
"contactCopied": "Contact copied.",
"urlCopied": "URL copied."
}
},
"relaysPage": { "relaysPage": {
"relayName": "Address", "relayName": "Address",
"globalFeed": "Global feed", "globalFeed": "Global feed",

View File

@ -151,6 +151,29 @@
"newMessages": "{{newNotesCount}} notas nuevas. Desliza para refrescar.", "newMessages": "{{newNotesCount}} notas nuevas. Desliza para refrescar.",
"myFeed": "My feed" "myFeed": "My feed"
}, },
"relayCard": {
"moreInfo": "More info",
"lessInfo": "Less info",
"globalFeed": "Global Feed",
"active": "Active",
"share": "Share",
"pubkey": "Public key",
"contact": "Contact",
"supportedNips": "Supported NIPs",
"software": "Sowftware",
"version": "Version",
"description": "Description",
"obtainingInfo": "Obtaining relay information",
"notifications": {
"active": "Relay actived.",
"desactive": "Relay desactivated.",
"globalFeedActive": "Global feed enabled.",
"globalFeedActiveUnactive": "Global feed disabled.",
"pubkeyCopied": "Public key copied.",
"contactCopied": "Contact copied.",
"urlCopied": "URL copied."
}
},
"relaysPage": { "relaysPage": {
"relayName": "Address", "relayName": "Address",
"globalFeed": "Global feed", "globalFeed": "Global feed",

View File

@ -34,14 +34,13 @@ import {
import RBSheet from 'react-native-raw-bottom-sheet' import RBSheet from 'react-native-raw-bottom-sheet'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons' import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import { useFocusEffect } from '@react-navigation/native' import { useFocusEffect } from '@react-navigation/native'
import ProfileCard from '../../Components/ProfileCard'
import ProfileData from '../../Components/ProfileData' import ProfileData from '../../Components/ProfileData'
import { handleInfinityScroll } from '../../Functions/NativeFunctions' import { handleInfinityScroll } from '../../Functions/NativeFunctions'
export const ContactsFeed: React.FC = () => { export const ContactsFeed: React.FC = () => {
const { t } = useTranslation('common') const { t } = useTranslation('common')
const initialPageSize = 20 const initialPageSize = 20
const { database } = useContext(AppContext) const { database, setDisplayUserDrawer } = useContext(AppContext)
const { privateKey, publicKey, nPub } = React.useContext(UserContext) const { privateKey, publicKey, nPub } = React.useContext(UserContext)
const { relayPool, lastEventId } = useContext(RelayPoolContext) const { relayPool, lastEventId } = useContext(RelayPoolContext)
const theme = useTheme() const theme = useTheme()
@ -52,7 +51,6 @@ export const ContactsFeed: React.FC = () => {
const [followers, setFollowers] = useState<User[]>([]) const [followers, setFollowers] = useState<User[]>([])
const [following, setFollowing] = useState<User[]>([]) const [following, setFollowing] = useState<User[]>([])
const [contactInput, setContactInput] = useState<string>() const [contactInput, setContactInput] = useState<string>()
const [profileCardPubkey, setProfileCardPubkey] = useState<string>()
const [isAddingContact, setIsAddingContact] = useState<boolean>(false) const [isAddingContact, setIsAddingContact] = useState<boolean>(false)
const [showNotification, setShowNotification] = useState<undefined | string>() const [showNotification, setShowNotification] = useState<undefined | string>()
const [tabKey, setTabKey] = React.useState('following') const [tabKey, setTabKey] = React.useState('following')
@ -165,7 +163,7 @@ export const ContactsFeed: React.FC = () => {
return ( return (
<TouchableRipple <TouchableRipple
onPress={() => { onPress={() => {
setProfileCardPubkey(item.id) setDisplayUserDrawer(item.id)
bottomSheetProfileRef.current?.open() bottomSheetProfileRef.current?.open()
}} }}
> >
@ -339,10 +337,6 @@ export const ContactsFeed: React.FC = () => {
extended={false} extended={false}
/> />
)} )}
<RBSheet ref={bottomSheetProfileRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
<ProfileCard userPubKey={profileCardPubkey ?? ''} bottomSheetRef={bottomSheetProfileRef} />
</RBSheet>
<RBSheet <RBSheet
ref={bottomSheetAddContactRef} ref={bottomSheetAddContactRef}
closeOnDragDown={true} closeOnDragDown={true}

View File

@ -15,14 +15,19 @@ import NotePage from '../NotePage'
import SendPage from '../SendPage' import SendPage from '../SendPage'
import ConversationPage from '../ConversationPage' import ConversationPage from '../ConversationPage'
import ConfigPage from '../ConfigPage' import ConfigPage from '../ConfigPage'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { AppContext } from '../../Contexts/AppContext'
import RelayCard from '../../Components/RelayCard'
export const HomeNavigator: React.FC = () => { export const HomeNavigator: React.FC = () => {
const theme = useTheme() const theme = useTheme()
const { t } = useTranslation('common') const { t } = useTranslation('common')
const { displayRelayDrawer, setDisplayrelayDrawer } = React.useContext(RelayPoolContext)
const { displayUserDrawer, setDisplayUserDrawer } = React.useContext(AppContext)
const bottomSheetRef = React.useRef<RBSheet>(null) const bottomSheetRef = React.useRef<RBSheet>(null)
const bottomSheetProfileRef = React.useRef<RBSheet>(null) const bottomSheetProfileRef = React.useRef<RBSheet>(null)
const bottomSheetRelayRef = React.useRef<RBSheet>(null)
const Stack = React.useMemo(() => createStackNavigator(), []) const Stack = React.useMemo(() => createStackNavigator(), [])
const [showProfile, setShowProfile] = React.useState<string>()
const cardStyleInterpolator = React.useMemo( const cardStyleInterpolator = React.useMemo(
() => () =>
Platform.OS === 'android' Platform.OS === 'android'
@ -49,6 +54,14 @@ export const HomeNavigator: React.FC = () => {
bottomSheetRef.current?.open() bottomSheetRef.current?.open()
} }
React.useEffect(() => {
if (displayRelayDrawer) bottomSheetRelayRef.current?.open()
}, [displayRelayDrawer])
React.useEffect(() => {
if (displayUserDrawer) bottomSheetProfileRef.current?.open()
}, [displayUserDrawer])
return ( return (
<> <>
<Stack.Navigator <Stack.Navigator
@ -78,8 +91,7 @@ export const HomeNavigator: React.FC = () => {
icon='dots-vertical' icon='dots-vertical'
onPress={() => { onPress={() => {
const params = route?.params as { pubKey: string } const params = route?.params as { pubKey: string }
setShowProfile(params?.pubKey ?? '') setDisplayUserDrawer(params?.pubKey ?? '')
bottomSheetProfileRef.current?.open()
}} }}
/> />
)} )}
@ -112,8 +124,21 @@ export const HomeNavigator: React.FC = () => {
<Stack.Screen name='Profile' component={ProfilePage} /> <Stack.Screen name='Profile' component={ProfilePage} />
</Stack.Group> </Stack.Group>
</Stack.Navigator> </Stack.Navigator>
<RBSheet ref={bottomSheetProfileRef} closeOnDragDown={true} customStyles={bottomSheetStyles}> <RBSheet
<ProfileCard userPubKey={showProfile ?? ''} bottomSheetRef={bottomSheetProfileRef} /> ref={bottomSheetProfileRef}
closeOnDragDown={true}
customStyles={bottomSheetStyles}
onClose={() => setDisplayUserDrawer(undefined)}
>
<ProfileCard bottomSheetRef={bottomSheetProfileRef} />
</RBSheet>
<RBSheet
ref={bottomSheetRelayRef}
closeOnDragDown={true}
customStyles={bottomSheetStyles}
onClose={() => setDisplayrelayDrawer(undefined)}
>
<RelayCard url={displayRelayDrawer} bottomSheetRef={bottomSheetRelayRef} />
</RBSheet> </RBSheet>
<RBSheet ref={bottomSheetRef} closeOnDragDown={true} customStyles={bottomSheetStyles}> <RBSheet ref={bottomSheetRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
<View> <View>

View File

@ -24,10 +24,9 @@ import { getUnixTime } from 'date-fns'
interface GlobalFeedProps { interface GlobalFeedProps {
navigation: any navigation: any
setProfileCardPubKey: (profileCardPubKey: string) => void
} }
export const GlobalFeed: React.FC<GlobalFeedProps> = ({ navigation, setProfileCardPubKey }) => { export const GlobalFeed: React.FC<GlobalFeedProps> = ({ navigation }) => {
const theme = useTheme() const theme = useTheme()
const { database, showPublicImages } = useContext(AppContext) const { database, showPublicImages } = useContext(AppContext)
const { publicKey } = useContext(UserContext) const { publicKey } = useContext(UserContext)
@ -115,9 +114,6 @@ export const GlobalFeed: React.FC<GlobalFeedProps> = ({ navigation, setProfileCa
note={item} note={item}
showActionCount={false} showActionCount={false}
showAvatarImage={showPublicImages} showAvatarImage={showPublicImages}
onPressUser={(user) => {
setProfileCardPubKey(user.id)
}}
showPreview={showPublicImages} showPreview={showPublicImages}
/> />
</View> </View>

View File

@ -1,16 +1,13 @@
import React, { useContext, useState } from 'react' import React, { useContext } from 'react'
import { Dimensions, ScrollView, StyleSheet, View } from 'react-native' import { Dimensions, ScrollView, StyleSheet, View } from 'react-native'
import { UserContext } from '../../Contexts/UserContext' import { UserContext } from '../../Contexts/UserContext'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext' import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { AnimatedFAB, Text, TouchableRipple } from 'react-native-paper' import { AnimatedFAB, Text, TouchableRipple } from 'react-native-paper'
import RBSheet from 'react-native-raw-bottom-sheet'
import ProfileCard from '../../Components/ProfileCard'
import { useFocusEffect, useTheme } from '@react-navigation/native' import { useFocusEffect, useTheme } from '@react-navigation/native'
import { navigate } from '../../lib/Navigation' import { navigate } from '../../lib/Navigation'
import { t } from 'i18next' import { t } from 'i18next'
import GlobalFeed from '../GlobalFeed' import GlobalFeed from '../GlobalFeed'
import MyFeed from '../MyFeed' import MyFeed from '../MyFeed'
import { AppContext } from '../../Contexts/AppContext'
import ReactionsFeed from '../ReactionsFeed' import ReactionsFeed from '../ReactionsFeed'
import RepostsFeed from '../RepostsFeed' import RepostsFeed from '../RepostsFeed'
@ -20,12 +17,9 @@ interface HomeFeedProps {
export const HomeFeed: React.FC<HomeFeedProps> = ({ navigation }) => { export const HomeFeed: React.FC<HomeFeedProps> = ({ navigation }) => {
const theme = useTheme() const theme = useTheme()
const { showPublicImages } = useContext(AppContext)
const { privateKey } = useContext(UserContext) const { privateKey } = useContext(UserContext)
const { relayPool } = useContext(RelayPoolContext) const { relayPool } = useContext(RelayPoolContext)
const [tabKey, setTabKey] = React.useState('myFeed') const [tabKey, setTabKey] = React.useState('myFeed')
const [profileCardPubkey, setProfileCardPubKey] = useState<string>()
const bottomSheetProfileRef = React.useRef<RBSheet>(null)
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
@ -40,58 +34,11 @@ export const HomeFeed: React.FC<HomeFeedProps> = ({ navigation }) => {
}, []), }, []),
) )
const bottomSheetStyles = React.useMemo(() => {
return {
container: {
backgroundColor: theme.colors.background,
paddingTop: 16,
paddingRight: 16,
paddingBottom: 32,
paddingLeft: 16,
borderTopRightRadius: 28,
borderTopLeftRadius: 28,
height: 'auto',
},
}
}, [])
const renderScene: Record<string, JSX.Element> = { const renderScene: Record<string, JSX.Element> = {
globalFeed: ( globalFeed: <GlobalFeed navigation={navigation} />,
<GlobalFeed myFeed: <MyFeed navigation={navigation} />,
navigation={navigation} reactions: <ReactionsFeed navigation={navigation} />,
setProfileCardPubKey={(value) => { reposts: <RepostsFeed navigation={navigation} />,
setProfileCardPubKey(value)
bottomSheetProfileRef.current?.open()
}}
/>
),
myFeed: (
<MyFeed
navigation={navigation}
setProfileCardPubKey={(value) => {
setProfileCardPubKey(value)
bottomSheetProfileRef.current?.open()
}}
/>
),
reactions: (
<ReactionsFeed
navigation={navigation}
setProfileCardPubKey={(value) => {
setProfileCardPubKey(value)
bottomSheetProfileRef.current?.open()
}}
/>
),
reposts: (
<RepostsFeed
navigation={navigation}
setProfileCardPubKey={(value) => {
setProfileCardPubKey(value)
bottomSheetProfileRef.current?.open()
}}
/>
),
} }
return ( return (
@ -196,13 +143,6 @@ export const HomeFeed: React.FC<HomeFeedProps> = ({ navigation }) => {
extended={false} extended={false}
/> />
)} )}
<RBSheet ref={bottomSheetProfileRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
<ProfileCard
userPubKey={profileCardPubkey ?? ''}
bottomSheetRef={bottomSheetProfileRef}
showImages={tabKey === 'myFeed' || showPublicImages}
/>
</RBSheet>
</View> </View>
) )
} }

View File

@ -24,10 +24,9 @@ import { useTranslation } from 'react-i18next'
interface MyFeedProps { interface MyFeedProps {
navigation: any navigation: any
setProfileCardPubKey: (profileCardPubKey: string) => void
} }
export const MyFeed: React.FC<MyFeedProps> = ({ navigation, setProfileCardPubKey }) => { export const MyFeed: React.FC<MyFeedProps> = ({ navigation }) => {
const theme = useTheme() const theme = useTheme()
const { t } = useTranslation('common') const { t } = useTranslation('common')
const { database } = useContext(AppContext) const { database } = useContext(AppContext)
@ -128,12 +127,7 @@ export const MyFeed: React.FC<MyFeedProps> = ({ navigation, setProfileCardPubKey
const renderItem: ListRenderItem<Note> = ({ item }) => { const renderItem: ListRenderItem<Note> = ({ item }) => {
return ( return (
<View style={styles.noteCard} key={item.id}> <View style={styles.noteCard} key={item.id}>
<NoteCard <NoteCard note={item} />
note={item}
onPressUser={(user) => {
setProfileCardPubKey(user.id)
}}
/>
</View> </View>
) )
} }

View File

@ -9,8 +9,6 @@ import { FlashList, ListRenderItem } from '@shopify/flash-list'
import { getDirectReplies } from '../../Functions/RelayFunctions/Events' import { getDirectReplies } from '../../Functions/RelayFunctions/Events'
import { AnimatedFAB, useTheme } from 'react-native-paper' import { AnimatedFAB, useTheme } from 'react-native-paper'
import { UserContext } from '../../Contexts/UserContext' import { UserContext } from '../../Contexts/UserContext'
import RBSheet from 'react-native-raw-bottom-sheet'
import ProfileCard from '../../Components/ProfileCard'
import { navigate } from '../../lib/Navigation' import { navigate } from '../../lib/Navigation'
import { useFocusEffect } from '@react-navigation/native' import { useFocusEffect } from '@react-navigation/native'
import { SkeletonNote } from '../../Components/SkeletonNote/SkeletonNote' import { SkeletonNote } from '../../Components/SkeletonNote/SkeletonNote'
@ -26,9 +24,7 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
const [note, setNote] = useState<Note>() const [note, setNote] = useState<Note>()
const [replies, setReplies] = useState<Note[]>() const [replies, setReplies] = useState<Note[]>()
const [refreshing, setRefreshing] = useState(false) const [refreshing, setRefreshing] = useState(false)
const [profileCardPubkey, setProfileCardPubKey] = useState<string>()
const theme = useTheme() const theme = useTheme()
const bottomSheetProfileRef = React.useRef<RBSheet>(null)
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
@ -98,42 +94,14 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
)} )}
</View> </View>
<View style={styles.noteCard}> <View style={styles.noteCard}>
<NoteCard <NoteCard note={item} showAnswerData={false} showRepostPreview={false} />
note={item}
onPressUser={(user) => {
setProfileCardPubKey(user.id)
bottomSheetProfileRef.current?.open()
}}
showAnswerData={false}
showRepostPreview={false}
/>
</View> </View>
</View> </View>
) )
const bottomSheetStyles = React.useMemo(() => {
return {
container: {
backgroundColor: theme.colors.background,
paddingTop: 16,
paddingRight: 16,
paddingBottom: 32,
paddingLeft: 16,
borderTopRightRadius: 28,
borderTopLeftRadius: 28,
height: 'auto',
},
}
}, [])
const openProfileDrawer: () => void = () => {
setProfileCardPubKey(note?.pubkey)
bottomSheetProfileRef.current?.open()
}
return note ? ( return note ? (
<View> <View>
<NoteCard note={note} onPressUser={openProfileDrawer} /> <NoteCard note={note} />
<View style={[styles.list, { borderColor: theme.colors.onSecondary }]}> <View style={[styles.list, { borderColor: theme.colors.onSecondary }]}>
<FlashList <FlashList
estimatedItemSize={200} estimatedItemSize={200}
@ -169,9 +137,6 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
iconMode='static' iconMode='static'
extended={false} extended={false}
/> />
<RBSheet ref={bottomSheetProfileRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
<ProfileCard userPubKey={profileCardPubkey ?? ''} bottomSheetRef={bottomSheetProfileRef} />
</RBSheet>
</View> </View>
) : ( ) : (
<View> <View>

View File

@ -14,9 +14,7 @@ import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { Kind } from 'nostr-tools' import { Kind } from 'nostr-tools'
import { handleInfinityScroll } from '../../Functions/NativeFunctions' import { handleInfinityScroll } from '../../Functions/NativeFunctions'
import { UserContext } from '../../Contexts/UserContext' import { UserContext } from '../../Contexts/UserContext'
import RBSheet from 'react-native-raw-bottom-sheet'
import { ActivityIndicator, Button, Text, useTheme } from 'react-native-paper' import { ActivityIndicator, Button, Text, useTheme } from 'react-native-paper'
import ProfileCard from '../../Components/ProfileCard'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons' import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { navigate } from '../../lib/Navigation' import { navigate } from '../../lib/Navigation'
@ -35,9 +33,7 @@ export const NotificationsFeed: React.FC = () => {
const { lastEventId, relayPool } = useContext(RelayPoolContext) const { lastEventId, relayPool } = useContext(RelayPoolContext)
const [pageSize, setPageSize] = useState<number>(initialPageSize) const [pageSize, setPageSize] = useState<number>(initialPageSize)
const [notes, setNotes] = useState<Note[]>([]) const [notes, setNotes] = useState<Note[]>([])
const bottomSheetProfileRef = React.useRef<RBSheet>(null)
const [refreshing, setRefreshing] = useState(true) const [refreshing, setRefreshing] = useState(true)
const [profileCardPubkey, setProfileCardPubKey] = useState<string>()
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
@ -143,13 +139,7 @@ export const NotificationsFeed: React.FC = () => {
const renderItem: ListRenderItem<Note> = ({ item }) => { const renderItem: ListRenderItem<Note> = ({ item }) => {
return ( return (
<View style={styles.noteCard} key={item.id}> <View style={styles.noteCard} key={item.id}>
<NoteCard <NoteCard note={item} />
note={item}
onPressUser={(user) => {
setProfileCardPubKey(user.id)
bottomSheetProfileRef.current?.open()
}}
/>
</View> </View>
) )
} }
@ -160,21 +150,6 @@ export const NotificationsFeed: React.FC = () => {
} }
} }
const bottomSheetStyles = React.useMemo(() => {
return {
container: {
backgroundColor: theme.colors.background,
paddingTop: 16,
paddingRight: 16,
paddingBottom: 32,
paddingLeft: 16,
borderTopRightRadius: 28,
borderTopLeftRadius: 28,
height: 'auto',
},
}
}, [])
const ListEmptyComponent = React.useMemo( const ListEmptyComponent = React.useMemo(
() => ( () => (
<View style={styles.blank}> <View style={styles.blank}>
@ -212,9 +187,6 @@ export const NotificationsFeed: React.FC = () => {
horizontal={false} horizontal={false}
ListFooterComponent={<ActivityIndicator animating={true} />} ListFooterComponent={<ActivityIndicator animating={true} />}
/> />
<RBSheet ref={bottomSheetProfileRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
<ProfileCard userPubKey={profileCardPubkey ?? ''} bottomSheetRef={bottomSheetProfileRef} />
</RBSheet>
</View> </View>
) )
} }

View File

@ -8,14 +8,7 @@ import {
View, View,
} from 'react-native' } from 'react-native'
import Clipboard from '@react-native-clipboard/clipboard' import Clipboard from '@react-native-clipboard/clipboard'
import { import { Surface, Text, IconButton, ActivityIndicator, Snackbar } from 'react-native-paper'
Surface,
Text,
IconButton,
ActivityIndicator,
useTheme,
Snackbar,
} from 'react-native-paper'
import { FlashList, ListRenderItem } from '@shopify/flash-list' import { FlashList, ListRenderItem } from '@shopify/flash-list'
import { AppContext } from '../../Contexts/AppContext' import { AppContext } from '../../Contexts/AppContext'
import { UserContext } from '../../Contexts/UserContext' import { UserContext } from '../../Contexts/UserContext'
@ -29,8 +22,6 @@ import { RelayFilters } from '../../lib/nostr/RelayPool/intex'
import NoteCard from '../../Components/NoteCard' import NoteCard from '../../Components/NoteCard'
import LnPayment from '../../Components/LnPayment' import LnPayment from '../../Components/LnPayment'
import { handleInfinityScroll } from '../../Functions/NativeFunctions' import { handleInfinityScroll } from '../../Functions/NativeFunctions'
import RBSheet from 'react-native-raw-bottom-sheet'
import ProfileCard from '../../Components/ProfileCard'
import { navigate } from '../../lib/Navigation' import { navigate } from '../../lib/Navigation'
import { useFocusEffect } from '@react-navigation/native' import { useFocusEffect } from '@react-navigation/native'
import { getNpub } from '../../lib/nostr/Nip19' import { getNpub } from '../../lib/nostr/Nip19'
@ -45,8 +36,6 @@ export const ProfilePage: React.FC<ProfilePageProps> = ({ route }) => {
const { publicKey } = useContext(UserContext) const { publicKey } = useContext(UserContext)
const { lastEventId, relayPool } = useContext(RelayPoolContext) const { lastEventId, relayPool } = useContext(RelayPoolContext)
const { t } = useTranslation('common') const { t } = useTranslation('common')
const bottomSheetProfileRef = React.useRef<RBSheet>(null)
const theme = useTheme()
const initialPageSize = 10 const initialPageSize = 10
const [showNotification, setShowNotification] = useState<undefined | string>() const [showNotification, setShowNotification] = useState<undefined | string>()
const [notes, setNotes] = useState<Note[]>() const [notes, setNotes] = useState<Note[]>()
@ -174,25 +163,10 @@ export const ProfilePage: React.FC<ProfilePageProps> = ({ route }) => {
const renderItem: ListRenderItem<Note> = ({ item }) => ( const renderItem: ListRenderItem<Note> = ({ item }) => (
<View style={styles.noteCard} key={item.id}> <View style={styles.noteCard} key={item.id}>
<NoteCard note={item} onPressUser={() => bottomSheetProfileRef.current?.open()} /> <NoteCard note={item} />
</View> </View>
) )
const bottomSheetStyles = React.useMemo(() => {
return {
container: {
backgroundColor: theme.colors.background,
paddingTop: 16,
paddingRight: 16,
paddingBottom: 32,
paddingLeft: 16,
borderTopRightRadius: 28,
borderTopLeftRadius: 28,
height: 'auto',
},
}
}, [])
return ( return (
<View> <View>
<ScrollView <ScrollView
@ -239,7 +213,6 @@ export const ProfilePage: React.FC<ProfilePageProps> = ({ route }) => {
pubKey: route.params.pubKey, pubKey: route.params.pubKey,
title: user ? username(user) : route.params.pubKey, title: user ? username(user) : route.params.pubKey,
}) })
bottomSheetProfileRef.current?.close()
}} }}
/> />
<Text>{t('profilePage.message')}</Text> <Text>{t('profilePage.message')}</Text>
@ -297,12 +270,6 @@ export const ProfilePage: React.FC<ProfilePageProps> = ({ route }) => {
</Snackbar> </Snackbar>
)} )}
<LnPayment setOpen={setOpenLn} open={openLn} user={user} /> <LnPayment setOpen={setOpenLn} open={openLn} user={user} />
<RBSheet ref={bottomSheetProfileRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
<ProfileCard
userPubKey={route.params.pubKey ?? ''}
bottomSheetRef={bottomSheetProfileRef}
/>
</RBSheet>
</View> </View>
) )
} }

View File

@ -23,13 +23,9 @@ import { getLastReaction } from '../../Functions/DatabaseFunctions/Reactions'
interface ReactionsFeedProps { interface ReactionsFeedProps {
navigation: any navigation: any
setProfileCardPubKey: (profileCardPubKey: string) => void
} }
export const ReactionsFeed: React.FC<ReactionsFeedProps> = ({ export const ReactionsFeed: React.FC<ReactionsFeedProps> = ({ navigation }) => {
navigation,
setProfileCardPubKey,
}) => {
const theme = useTheme() const theme = useTheme()
const { database } = useContext(AppContext) const { database } = useContext(AppContext)
const { publicKey } = useContext(UserContext) const { publicKey } = useContext(UserContext)
@ -126,12 +122,7 @@ export const ReactionsFeed: React.FC<ReactionsFeedProps> = ({
const renderItem: ListRenderItem<Note> = ({ item }) => { const renderItem: ListRenderItem<Note> = ({ item }) => {
return ( return (
<View style={styles.noteCard} key={item.id}> <View style={styles.noteCard} key={item.id}>
<NoteCard <NoteCard note={item} />
note={item}
onPressUser={(user) => {
setProfileCardPubKey(user.id)
}}
/>
</View> </View>
) )
} }

View File

@ -23,10 +23,9 @@ import { getLastReaction } from '../../Functions/DatabaseFunctions/Reactions'
interface RepostsFeedProps { interface RepostsFeedProps {
navigation: any navigation: any
setProfileCardPubKey: (profileCardPubKey: string) => void
} }
export const RepostsFeed: React.FC<RepostsFeedProps> = ({ navigation, setProfileCardPubKey }) => { export const RepostsFeed: React.FC<RepostsFeedProps> = ({ navigation }) => {
const theme = useTheme() const theme = useTheme()
const { database } = useContext(AppContext) const { database } = useContext(AppContext)
const { publicKey } = useContext(UserContext) const { publicKey } = useContext(UserContext)
@ -123,12 +122,7 @@ export const RepostsFeed: React.FC<RepostsFeedProps> = ({ navigation, setProfile
const renderItem: ListRenderItem<Note> = ({ item }) => { const renderItem: ListRenderItem<Note> = ({ item }) => {
return ( return (
<View style={styles.noteCard} key={item.id}> <View style={styles.noteCard} key={item.id}>
<NoteCard <NoteCard note={item} />
note={item}
onPressUser={(user) => {
setProfileCardPubKey(user.id)
}}
/>
</View> </View>
) )
} }

View File

@ -1,6 +1,7 @@
import { decode, EventPointer, npubEncode, ProfilePointer } from 'nostr-tools/nip19' import { decode, EventPointer, npubEncode, ProfilePointer } from 'nostr-tools/nip19'
export function getNpub(key: string): string { export function getNpub(key: string | undefined): string {
if (!key) return ''
if (isPublicKey(key)) return key if (isPublicKey(key)) return key
try { try {

View File

@ -48,7 +48,7 @@
"react-native-paper": "^5.1.3", "react-native-paper": "^5.1.3",
"react-native-parsed-text": "^0.0.22", "react-native-parsed-text": "^0.0.22",
"react-native-qrcode-svg": "^6.1.2", "react-native-qrcode-svg": "^6.1.2",
"react-native-quick-sqlite": "^6.1.1", "react-native-quick-sqlite": "^7.0.0",
"react-native-raw-bottom-sheet": "^2.2.0", "react-native-raw-bottom-sheet": "^2.2.0",
"react-native-reanimated": "^2.14.2", "react-native-reanimated": "^2.14.2",
"react-native-safe-area-context": "^4.4.1", "react-native-safe-area-context": "^4.4.1",

View File

@ -7252,10 +7252,10 @@ react-native-qrcode-svg@^6.1.2:
prop-types "^15.7.2" prop-types "^15.7.2"
qrcode "^1.5.0" qrcode "^1.5.0"
react-native-quick-sqlite@^6.1.1: react-native-quick-sqlite@^7.0.0:
version "6.1.1" version "7.0.0"
resolved "https://registry.yarnpkg.com/react-native-quick-sqlite/-/react-native-quick-sqlite-6.1.1.tgz#ba35d0a4a919a5a0962306c3fee4dc46983b0839" resolved "https://registry.yarnpkg.com/react-native-quick-sqlite/-/react-native-quick-sqlite-7.0.0.tgz#a8bd9344a784f391392d5ac703ebd1d6db06889f"
integrity sha512-bVV7+mWAhWH/0iPjQmDlLHqTIkYm+j+k5pFiy+3jW91DnkH44C0tR4DSeRa6ERLz1fG/lDB1KwcBU3fOL9vFCA== integrity sha512-SSJeC2ERhZz90IhCr4MZIs34+OStnfD7ziCi+XC43/YU/eymC4ko9pFmnb57e4bPRjkT891C4D4R+c2TM7QzeQ==
react-native-raw-bottom-sheet@^2.2.0: react-native-raw-bottom-sheet@^2.2.0:
version "2.2.0" version "2.2.0"